server.go 19 KB

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