github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/http3/server.go (about)

     1  package http3
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/tls"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"net"
    11  	"net/http"
    12  	"runtime"
    13  	"strings"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go"
    18  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/handshake"
    19  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol"
    20  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/utils"
    21  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/quicvarint"
    22  	"github.com/marten-seemann/qpack"
    23  )
    24  
    25  // allows mocking of quic.Listen and quic.ListenAddr
    26  var (
    27  	quicListen     = quic.ListenEarly
    28  	quicListenAddr = quic.ListenAddrEarly
    29  )
    30  
    31  const (
    32  	nextProtoH3Draft29 = "h3-29"
    33  	nextProtoH3        = "h3"
    34  )
    35  
    36  const (
    37  	streamTypeControlStream      = 0
    38  	streamTypePushStream         = 1
    39  	streamTypeQPACKEncoderStream = 2
    40  	streamTypeQPACKDecoderStream = 3
    41  )
    42  
    43  func versionToALPN(v protocol.VersionNumber) string {
    44  	if v == protocol.Version1 {
    45  		return nextProtoH3
    46  	}
    47  	if v == protocol.VersionTLS || v == protocol.VersionDraft29 {
    48  		return nextProtoH3Draft29
    49  	}
    50  	return ""
    51  }
    52  
    53  // ConfigureTLSConfig creates a new tls.Config which can be used
    54  // to create a quic.Listener meant for serving http3. The created
    55  // tls.Config adds the functionality of detecting the used QUIC version
    56  // in order to set the correct ALPN value for the http3 connection.
    57  func ConfigureTLSConfig(tlsConf *tls.Config) *tls.Config {
    58  	// The tls.Config used to setup the quic.Listener needs to have the GetConfigForClient callback set.
    59  	// That way, we can get the QUIC version and set the correct ALPN value.
    60  	return &tls.Config{
    61  		GetConfigForClient: func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
    62  			// determine the ALPN from the QUIC version used
    63  			proto := nextProtoH3Draft29
    64  			if qconn, ok := ch.Conn.(handshake.ConnWithVersion); ok {
    65  				if qconn.GetQUICVersion() == protocol.Version1 {
    66  					proto = nextProtoH3
    67  				}
    68  			}
    69  			config := tlsConf
    70  			if tlsConf.GetConfigForClient != nil {
    71  				getConfigForClient := tlsConf.GetConfigForClient
    72  				var err error
    73  				conf, err := getConfigForClient(ch)
    74  				if err != nil {
    75  					return nil, err
    76  				}
    77  				if conf != nil {
    78  					config = conf
    79  				}
    80  			}
    81  			if config == nil {
    82  				return nil, nil
    83  			}
    84  			config = config.Clone()
    85  			config.NextProtos = []string{proto}
    86  			return config, nil
    87  		},
    88  	}
    89  }
    90  
    91  // contextKey is a value for use with context.WithValue. It's used as
    92  // a pointer so it fits in an interface{} without allocation.
    93  type contextKey struct {
    94  	name string
    95  }
    96  
    97  func (k *contextKey) String() string { return "quic-go/http3 context value " + k.name }
    98  
    99  // ServerContextKey is a context key. It can be used in HTTP
   100  // handlers with Context.Value to access the server that
   101  // started the handler. The associated value will be of
   102  // type *http3.Server.
   103  var ServerContextKey = &contextKey{"http3-server"}
   104  
   105  type requestError struct {
   106  	err       error
   107  	streamErr errorCode
   108  	connErr   errorCode
   109  }
   110  
   111  func newStreamError(code errorCode, err error) requestError {
   112  	return requestError{err: err, streamErr: code}
   113  }
   114  
   115  func newConnError(code errorCode, err error) requestError {
   116  	return requestError{err: err, connErr: code}
   117  }
   118  
   119  // listenerInfo contains info about specific listener added with addListener
   120  type listenerInfo struct {
   121  	port int // 0 means that no info about port is available
   122  }
   123  
   124  // Server is a HTTP/3 server.
   125  type Server struct {
   126  	*http.Server
   127  
   128  	// By providing a quic.Config, it is possible to set parameters of the QUIC connection.
   129  	// If nil, it uses reasonable default values.
   130  	QuicConfig *quic.Config
   131  
   132  	// Enable support for HTTP/3 datagrams.
   133  	// If set to true, QuicConfig.EnableDatagram will be set.
   134  	// See https://www.ietf.org/archive/id/draft-schinazi-masque-h3-datagram-02.html.
   135  	EnableDatagrams bool
   136  
   137  	// The port to use in Alt-Svc response headers.
   138  	// If needed Port can be manually set when the Server is created.
   139  	// This is useful when a Layer 4 firewall is redirecting UDP traffic and clients must use
   140  	// a port different from the port the Server is listening on.
   141  	Port int
   142  
   143  	mutex     sync.RWMutex
   144  	listeners map[*quic.EarlyListener]listenerInfo
   145  	closed    utils.AtomicBool
   146  
   147  	altSvcHeader string
   148  
   149  	loggerOnce sync.Once
   150  	logger     utils.Logger
   151  }
   152  
   153  // ListenAndServe listens on the UDP address s.Addr and calls s.Handler to handle HTTP/3 requests on incoming connections.
   154  func (s *Server) ListenAndServe() error {
   155  	if s.Server == nil {
   156  		return errors.New("use of http3.Server without http.Server")
   157  	}
   158  	return s.serveConn(s.TLSConfig, nil)
   159  }
   160  
   161  // ListenAndServeTLS listens on the UDP address s.Addr and calls s.Handler to handle HTTP/3 requests on incoming connections.
   162  func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
   163  	var err error
   164  	certs := make([]tls.Certificate, 1)
   165  	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
   166  	if err != nil {
   167  		return err
   168  	}
   169  	// We currently only use the cert-related stuff from tls.Config,
   170  	// so we don't need to make a full copy.
   171  	config := &tls.Config{
   172  		Certificates: certs,
   173  	}
   174  	return s.serveConn(config, nil)
   175  }
   176  
   177  // Serve an existing UDP connection.
   178  // It is possible to reuse the same connection for outgoing connections.
   179  // Closing the server does not close the packet conn.
   180  func (s *Server) Serve(conn net.PacketConn) error {
   181  	return s.serveConn(s.TLSConfig, conn)
   182  }
   183  
   184  // Serve an existing QUIC listener.
   185  // Make sure you use http3.ConfigureTLSConfig to configure a tls.Config
   186  // and use it to construct a http3-friendly QUIC listener.
   187  // Closing the server does close the listener.
   188  func (s *Server) ServeListener(listener quic.EarlyListener) error {
   189  	return s.serveImpl(func() (quic.EarlyListener, error) { return listener, nil })
   190  }
   191  
   192  func (s *Server) serveConn(tlsConf *tls.Config, conn net.PacketConn) error {
   193  	return s.serveImpl(func() (quic.EarlyListener, error) {
   194  		baseConf := ConfigureTLSConfig(tlsConf)
   195  		quicConf := s.QuicConfig
   196  		if quicConf == nil {
   197  			quicConf = &quic.Config{}
   198  		} else {
   199  			quicConf = s.QuicConfig.Clone()
   200  		}
   201  		if s.EnableDatagrams {
   202  			quicConf.EnableDatagrams = true
   203  		}
   204  
   205  		var ln quic.EarlyListener
   206  		var err error
   207  		if conn == nil {
   208  			ln, err = quicListenAddr(s.Addr, baseConf, quicConf)
   209  		} else {
   210  			ln, err = quicListen(conn, baseConf, quicConf)
   211  		}
   212  		if err != nil {
   213  			return nil, err
   214  		}
   215  		return ln, nil
   216  	})
   217  }
   218  
   219  func (s *Server) serveImpl(startListener func() (quic.EarlyListener, error)) error {
   220  	if s.closed.Get() {
   221  		return http.ErrServerClosed
   222  	}
   223  	if s.Server == nil {
   224  		return errors.New("use of http3.Server without http.Server")
   225  	}
   226  	s.loggerOnce.Do(func() {
   227  		s.logger = utils.DefaultLogger.WithPrefix("server")
   228  	})
   229  
   230  	ln, err := startListener()
   231  	if err != nil {
   232  		return err
   233  	}
   234  	s.addListener(&ln)
   235  	defer s.removeListener(&ln)
   236  
   237  	for {
   238  		sess, err := ln.Accept(context.Background())
   239  		if err != nil {
   240  			return err
   241  		}
   242  		go s.handleConn(sess)
   243  	}
   244  }
   245  
   246  func extractPort(addr string) (int, error) {
   247  	_, portStr, err := net.SplitHostPort(addr)
   248  	if err != nil {
   249  		return 0, err
   250  	}
   251  
   252  	portInt, err := net.LookupPort("tcp", portStr)
   253  	if err != nil {
   254  		return 0, err
   255  	}
   256  	return portInt, nil
   257  }
   258  
   259  func (s *Server) generateAltSvcHeader() {
   260  	if len(s.listeners) == 0 {
   261  		// Don't announce any ports since no one is listening for connections
   262  		s.altSvcHeader = ""
   263  		return
   264  	}
   265  
   266  	// This code assumes that we will use protocol.SupportedVersions if no quic.Config is passed.
   267  	supportedVersions := protocol.SupportedVersions
   268  	if s.QuicConfig != nil && len(s.QuicConfig.Versions) > 0 {
   269  		supportedVersions = s.QuicConfig.Versions
   270  	}
   271  	var versionStrings []string
   272  	for _, version := range supportedVersions {
   273  		if v := versionToALPN(version); len(v) > 0 {
   274  			versionStrings = append(versionStrings, v)
   275  		}
   276  	}
   277  
   278  	var altSvc []string
   279  	addPort := func(port int) {
   280  		for _, v := range versionStrings {
   281  			altSvc = append(altSvc, fmt.Sprintf(`%s=":%d"; ma=2592000`, v, port))
   282  		}
   283  	}
   284  
   285  	if s.Port != 0 {
   286  		// if Port is specified, we must use it instead of the
   287  		// listener addresses since there's a reason it's specified.
   288  		addPort(s.Port)
   289  	} else {
   290  		// if we have some listeners assigned, try to find ports
   291  		// which we can announce, otherwise nothing should be announced
   292  		validPortsFound := false
   293  		for _, info := range s.listeners {
   294  			if info.port != 0 {
   295  				addPort(info.port)
   296  				validPortsFound = true
   297  			}
   298  		}
   299  		if !validPortsFound {
   300  			if port, err := extractPort(s.Addr); err == nil {
   301  				addPort(port)
   302  			}
   303  		}
   304  	}
   305  
   306  	s.altSvcHeader = strings.Join(altSvc, ",")
   307  }
   308  
   309  // We store a pointer to interface in the map set. This is safe because we only
   310  // call trackListener via Serve and can track+defer untrack the same pointer to
   311  // local variable there. We never need to compare a Listener from another caller.
   312  func (s *Server) addListener(l *quic.EarlyListener) {
   313  	s.mutex.Lock()
   314  	if s.listeners == nil {
   315  		s.listeners = make(map[*quic.EarlyListener]listenerInfo)
   316  	}
   317  
   318  	if port, err := extractPort((*l).Addr().String()); err == nil {
   319  		s.listeners[l] = listenerInfo{port}
   320  	} else {
   321  		s.logger.Errorf(
   322  			"Unable to extract port from listener %+v, will not be announced using SetQuicHeaders: %s", err)
   323  		s.listeners[l] = listenerInfo{}
   324  	}
   325  	s.generateAltSvcHeader()
   326  
   327  	s.mutex.Unlock()
   328  }
   329  
   330  func (s *Server) removeListener(l *quic.EarlyListener) {
   331  	s.mutex.Lock()
   332  	delete(s.listeners, l)
   333  	s.generateAltSvcHeader()
   334  	s.mutex.Unlock()
   335  }
   336  
   337  func (s *Server) handleConn(sess quic.EarlySession) {
   338  	decoder := qpack.NewDecoder(nil)
   339  
   340  	// send a SETTINGS frame
   341  	str, err := sess.OpenUniStream()
   342  	if err != nil {
   343  		s.logger.Debugf("Opening the control stream failed.")
   344  		return
   345  	}
   346  	buf := &bytes.Buffer{}
   347  	quicvarint.Write(buf, streamTypeControlStream) // stream type
   348  	(&settingsFrame{Datagram: s.EnableDatagrams}).Write(buf)
   349  	str.Write(buf.Bytes())
   350  
   351  	go s.handleUnidirectionalStreams(sess)
   352  
   353  	// Process all requests immediately.
   354  	// It's the client's responsibility to decide which requests are eligible for 0-RTT.
   355  	for {
   356  		str, err := sess.AcceptStream(context.Background())
   357  		if err != nil {
   358  			s.logger.Debugf("Accepting stream failed: %s", err)
   359  			return
   360  		}
   361  		go func() {
   362  			rerr := s.handleRequest(sess, str, decoder, func() {
   363  				sess.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "")
   364  			})
   365  			if rerr.err != nil || rerr.streamErr != 0 || rerr.connErr != 0 {
   366  				s.logger.Debugf("Handling request failed: %s", err)
   367  				if rerr.streamErr != 0 {
   368  					str.CancelWrite(quic.StreamErrorCode(rerr.streamErr))
   369  				}
   370  				if rerr.connErr != 0 {
   371  					var reason string
   372  					if rerr.err != nil {
   373  						reason = rerr.err.Error()
   374  					}
   375  					sess.CloseWithError(quic.ApplicationErrorCode(rerr.connErr), reason)
   376  				}
   377  				return
   378  			}
   379  			str.Close()
   380  		}()
   381  	}
   382  }
   383  
   384  func (s *Server) handleUnidirectionalStreams(sess quic.EarlySession) {
   385  	for {
   386  		str, err := sess.AcceptUniStream(context.Background())
   387  		if err != nil {
   388  			s.logger.Debugf("accepting unidirectional stream failed: %s", err)
   389  			return
   390  		}
   391  
   392  		go func(str quic.ReceiveStream) {
   393  			streamType, err := quicvarint.Read(quicvarint.NewReader(str))
   394  			if err != nil {
   395  				s.logger.Debugf("reading stream type on stream %d failed: %s", str.StreamID(), err)
   396  				return
   397  			}
   398  			// We're only interested in the control stream here.
   399  			switch streamType {
   400  			case streamTypeControlStream:
   401  			case streamTypeQPACKEncoderStream, streamTypeQPACKDecoderStream:
   402  				// Our QPACK implementation doesn't use the dynamic table yet.
   403  				// TODO: check that only one stream of each type is opened.
   404  				return
   405  			case streamTypePushStream: // only the server can push
   406  				sess.CloseWithError(quic.ApplicationErrorCode(errorStreamCreationError), "")
   407  				return
   408  			default:
   409  				str.CancelRead(quic.StreamErrorCode(errorStreamCreationError))
   410  				return
   411  			}
   412  			f, err := parseNextFrame(str)
   413  			if err != nil {
   414  				sess.CloseWithError(quic.ApplicationErrorCode(errorFrameError), "")
   415  				return
   416  			}
   417  			sf, ok := f.(*settingsFrame)
   418  			if !ok {
   419  				sess.CloseWithError(quic.ApplicationErrorCode(errorMissingSettings), "")
   420  				return
   421  			}
   422  			if !sf.Datagram {
   423  				return
   424  			}
   425  			// If datagram support was enabled on our side as well as on the client side,
   426  			// we can expect it to have been negotiated both on the transport and on the HTTP/3 layer.
   427  			// Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT).
   428  			if s.EnableDatagrams && !sess.ConnectionState().SupportsDatagrams {
   429  				sess.CloseWithError(quic.ApplicationErrorCode(errorSettingsError), "missing QUIC Datagram support")
   430  			}
   431  		}(str)
   432  	}
   433  }
   434  
   435  func (s *Server) maxHeaderBytes() uint64 {
   436  	if s.Server.MaxHeaderBytes <= 0 {
   437  		return http.DefaultMaxHeaderBytes
   438  	}
   439  	return uint64(s.Server.MaxHeaderBytes)
   440  }
   441  
   442  func (s *Server) handleRequest(sess quic.Session, str quic.Stream, decoder *qpack.Decoder, onFrameError func()) requestError {
   443  	frame, err := parseNextFrame(str)
   444  	if err != nil {
   445  		return newStreamError(errorRequestIncomplete, err)
   446  	}
   447  	hf, ok := frame.(*headersFrame)
   448  	if !ok {
   449  		return newConnError(errorFrameUnexpected, errors.New("expected first frame to be a HEADERS frame"))
   450  	}
   451  	if hf.Length > s.maxHeaderBytes() {
   452  		return newStreamError(errorFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, s.maxHeaderBytes()))
   453  	}
   454  	headerBlock := make([]byte, hf.Length)
   455  	if _, err := io.ReadFull(str, headerBlock); err != nil {
   456  		return newStreamError(errorRequestIncomplete, err)
   457  	}
   458  	hfs, err := decoder.DecodeFull(headerBlock)
   459  	if err != nil {
   460  		// TODO: use the right error code
   461  		return newConnError(errorGeneralProtocolError, err)
   462  	}
   463  	req, err := requestFromHeaders(hfs)
   464  	if err != nil {
   465  		// TODO: use the right error code
   466  		return newStreamError(errorGeneralProtocolError, err)
   467  	}
   468  
   469  	req.RemoteAddr = sess.RemoteAddr().String()
   470  	req.Body = newRequestBody(str, onFrameError)
   471  
   472  	if s.logger.Debug() {
   473  		s.logger.Infof("%s %s%s, on stream %d", req.Method, req.Host, req.RequestURI, str.StreamID())
   474  	} else {
   475  		s.logger.Infof("%s %s%s", req.Method, req.Host, req.RequestURI)
   476  	}
   477  
   478  	ctx := str.Context()
   479  	ctx = context.WithValue(ctx, ServerContextKey, s)
   480  	ctx = context.WithValue(ctx, http.LocalAddrContextKey, sess.LocalAddr())
   481  	req = req.WithContext(ctx)
   482  	r := newResponseWriter(str, s.logger)
   483  	defer func() {
   484  		if !r.usedDataStream() {
   485  			r.Flush()
   486  		}
   487  	}()
   488  	handler := s.Handler
   489  	if handler == nil {
   490  		handler = http.DefaultServeMux
   491  	}
   492  
   493  	var panicked bool
   494  	func() {
   495  		defer func() {
   496  			if p := recover(); p != nil {
   497  				// Copied from net/http/server.go
   498  				const size = 64 << 10
   499  				buf := make([]byte, size)
   500  				buf = buf[:runtime.Stack(buf, false)]
   501  				s.logger.Errorf("http: panic serving: %v\n%s", p, buf)
   502  				panicked = true
   503  			}
   504  		}()
   505  		handler.ServeHTTP(r, req)
   506  	}()
   507  
   508  	if !r.usedDataStream() {
   509  		if panicked {
   510  			r.WriteHeader(500)
   511  		} else {
   512  			r.WriteHeader(200)
   513  		}
   514  		// If the EOF was read by the handler, CancelRead() is a no-op.
   515  		str.CancelRead(quic.StreamErrorCode(errorNoError))
   516  	}
   517  	return requestError{}
   518  }
   519  
   520  // Close the server immediately, aborting requests and sending CONNECTION_CLOSE frames to connected clients.
   521  // Close in combination with ListenAndServe() (instead of Serve()) may race if it is called before a UDP socket is established.
   522  func (s *Server) Close() error {
   523  	s.closed.Set(true)
   524  
   525  	s.mutex.Lock()
   526  	defer s.mutex.Unlock()
   527  
   528  	var err error
   529  	for ln := range s.listeners {
   530  		if cerr := (*ln).Close(); cerr != nil && err == nil {
   531  			err = cerr
   532  		}
   533  	}
   534  	return err
   535  }
   536  
   537  // CloseGracefully shuts down the server gracefully. The server sends a GOAWAY frame first, then waits for either timeout to trigger, or for all running requests to complete.
   538  // CloseGracefully in combination with ListenAndServe() (instead of Serve()) may race if it is called before a UDP socket is established.
   539  func (s *Server) CloseGracefully(timeout time.Duration) error {
   540  	// TODO: implement
   541  	return nil
   542  }
   543  
   544  // ErrNoAltSvcPort is the error returned by SetQuicHeaders when no port was found
   545  // for Alt-Svc to announce. This can happen if listening on a PacketConn without a port
   546  // (UNIX socket, for example) and no port is specified in Server.Port or Server.Addr.
   547  var ErrNoAltSvcPort = errors.New("no port can be announced, specify it explicitly using Server.Port or Server.Addr")
   548  
   549  // SetQuicHeaders can be used to set the proper headers that announce that this server supports HTTP/3.
   550  // The values set by default advertise all of the ports the server is listening on, but can be
   551  // changed to a specific port by setting Server.Port before launching the serverr.
   552  // If no listener's Addr().String() returns an address with a valid port, Server.Addr will be used
   553  // to extract the port, if specified.
   554  // For example, a server launched using ListenAndServe on an address with port 443 would set:
   555  // 	Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
   556  func (s *Server) SetQuicHeaders(hdr http.Header) error {
   557  	s.mutex.RLock()
   558  	defer s.mutex.RUnlock()
   559  
   560  	if s.altSvcHeader == "" {
   561  		return ErrNoAltSvcPort
   562  	}
   563  	// use the map directly to avoid constant canonicalization
   564  	// since the key is already canonicalized
   565  	hdr["Alt-Svc"] = append(hdr["Alt-Svc"], s.altSvcHeader)
   566  	return nil
   567  }
   568  
   569  // ListenAndServeQUIC listens on the UDP network address addr and calls the
   570  // handler for HTTP/3 requests on incoming connections. http.DefaultServeMux is
   571  // used when handler is nil.
   572  func ListenAndServeQUIC(addr, certFile, keyFile string, handler http.Handler) error {
   573  	server := &Server{
   574  		Server: &http.Server{
   575  			Addr:    addr,
   576  			Handler: handler,
   577  		},
   578  	}
   579  	return server.ListenAndServeTLS(certFile, keyFile)
   580  }
   581  
   582  // ListenAndServe listens on the given network address for both, TLS and QUIC
   583  // connections in parallel. It returns if one of the two returns an error.
   584  // http.DefaultServeMux is used when handler is nil.
   585  // The correct Alt-Svc headers for QUIC are set.
   586  func ListenAndServe(addr, certFile, keyFile string, handler http.Handler) error {
   587  	// Load certs
   588  	var err error
   589  	certs := make([]tls.Certificate, 1)
   590  	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
   591  	if err != nil {
   592  		return err
   593  	}
   594  	// We currently only use the cert-related stuff from tls.Config,
   595  	// so we don't need to make a full copy.
   596  	config := &tls.Config{
   597  		Certificates: certs,
   598  	}
   599  
   600  	// Open the listeners
   601  	udpAddr, err := net.ResolveUDPAddr("udp", addr)
   602  	if err != nil {
   603  		return err
   604  	}
   605  	udpConn, err := net.ListenUDP("udp", udpAddr)
   606  	if err != nil {
   607  		return err
   608  	}
   609  	defer udpConn.Close()
   610  
   611  	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
   612  	if err != nil {
   613  		return err
   614  	}
   615  	tcpConn, err := net.ListenTCP("tcp", tcpAddr)
   616  	if err != nil {
   617  		return err
   618  	}
   619  	defer tcpConn.Close()
   620  
   621  	tlsConn := tls.NewListener(tcpConn, config)
   622  	defer tlsConn.Close()
   623  
   624  	// Start the servers
   625  	httpServer := &http.Server{
   626  		Addr:      addr,
   627  		TLSConfig: config,
   628  	}
   629  
   630  	quicServer := &Server{
   631  		Server: httpServer,
   632  	}
   633  
   634  	if handler == nil {
   635  		handler = http.DefaultServeMux
   636  	}
   637  	httpServer.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   638  		quicServer.SetQuicHeaders(w.Header())
   639  		handler.ServeHTTP(w, r)
   640  	})
   641  
   642  	hErr := make(chan error)
   643  	qErr := make(chan error)
   644  	go func() {
   645  		hErr <- httpServer.Serve(tlsConn)
   646  	}()
   647  	go func() {
   648  		qErr <- quicServer.Serve(udpConn)
   649  	}()
   650  
   651  	select {
   652  	case err := <-hErr:
   653  		quicServer.Close()
   654  		return err
   655  	case err := <-qErr:
   656  		// Cannot close the HTTP server or wait for requests to complete properly :/
   657  		return err
   658  	}
   659  }