server.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. package http3
  2. import (
  3. "context"
  4. tls "github.com/Psiphon-Labs/psiphon-tls"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "log/slog"
  9. "net"
  10. "net/http"
  11. "runtime"
  12. "strconv"
  13. "strings"
  14. "sync"
  15. "sync/atomic"
  16. "time"
  17. "github.com/Psiphon-Labs/quic-go"
  18. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  19. "github.com/Psiphon-Labs/quic-go/quicvarint"
  20. "github.com/quic-go/qpack"
  21. )
  22. // allows mocking of quic.Listen and quic.ListenAddr
  23. var (
  24. quicListen = func(conn net.PacketConn, tlsConf *tls.Config, config *quic.Config) (QUICEarlyListener, error) {
  25. return quic.ListenEarly(conn, tlsConf, config)
  26. }
  27. quicListenAddr = func(addr string, tlsConf *tls.Config, config *quic.Config) (QUICEarlyListener, error) {
  28. return quic.ListenAddrEarly(addr, tlsConf, config)
  29. }
  30. )
  31. // NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2.
  32. const NextProtoH3 = "h3"
  33. // StreamType is the stream type of a unidirectional stream.
  34. type StreamType uint64
  35. const (
  36. streamTypeControlStream = 0
  37. streamTypePushStream = 1
  38. streamTypeQPACKEncoderStream = 2
  39. streamTypeQPACKDecoderStream = 3
  40. )
  41. const goawayTimeout = 5 * time.Second
  42. // A QUICEarlyListener listens for incoming QUIC connections.
  43. type QUICEarlyListener interface {
  44. Accept(context.Context) (quic.EarlyConnection, error)
  45. Addr() net.Addr
  46. io.Closer
  47. }
  48. var _ QUICEarlyListener = &quic.EarlyListener{}
  49. func versionToALPN(v protocol.Version) string {
  50. //nolint:exhaustive // These are all the versions we care about.
  51. switch v {
  52. case protocol.Version1, protocol.Version2:
  53. return NextProtoH3
  54. default:
  55. return ""
  56. }
  57. }
  58. // ConfigureTLSConfig creates a new tls.Config which can be used
  59. // to create a quic.Listener meant for serving http3. The created
  60. // tls.Config adds the functionality of detecting the used QUIC version
  61. // in order to set the correct ALPN value for the http3 connection.
  62. func ConfigureTLSConfig(tlsConf *tls.Config) *tls.Config {
  63. // The tls.Config used to setup the quic.Listener needs to have the GetConfigForClient callback set.
  64. // That way, we can get the QUIC version and set the correct ALPN value.
  65. return &tls.Config{
  66. GetConfigForClient: func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
  67. // determine the ALPN from the QUIC version used
  68. proto := NextProtoH3
  69. val := ch.Context().Value(quic.QUICVersionContextKey)
  70. if v, ok := val.(quic.Version); ok {
  71. proto = versionToALPN(v)
  72. }
  73. config := tlsConf
  74. if tlsConf.GetConfigForClient != nil {
  75. getConfigForClient := tlsConf.GetConfigForClient
  76. var err error
  77. conf, err := getConfigForClient(ch)
  78. if err != nil {
  79. return nil, err
  80. }
  81. if conf != nil {
  82. config = conf
  83. }
  84. }
  85. if config == nil {
  86. return nil, nil
  87. }
  88. // Workaround for https://github.com/golang/go/issues/60506.
  89. // This initializes the session tickets _before_ cloning the config.
  90. _, _ = config.DecryptTicket(nil, tls.ConnectionState{})
  91. config = config.Clone()
  92. config.NextProtos = []string{proto}
  93. return config, nil
  94. },
  95. }
  96. }
  97. // contextKey is a value for use with context.WithValue. It's used as
  98. // a pointer so it fits in an interface{} without allocation.
  99. type contextKey struct {
  100. name string
  101. }
  102. func (k *contextKey) String() string { return "quic-go/http3 context value " + k.name }
  103. // ServerContextKey is a context key. It can be used in HTTP
  104. // handlers with Context.Value to access the server that
  105. // started the handler. The associated value will be of
  106. // type *http3.Server.
  107. var ServerContextKey = &contextKey{"http3-server"}
  108. // RemoteAddrContextKey is a context key. It can be used in
  109. // HTTP handlers with Context.Value to access the remote
  110. // address of the connection. The associated value will be of
  111. // type net.Addr.
  112. //
  113. // Use this value instead of [http.Request.RemoteAddr] if you
  114. // require access to the remote address of the connection rather
  115. // than its string representation.
  116. var RemoteAddrContextKey = &contextKey{"remote-addr"}
  117. // listenerInfo contains info about specific listener added with addListener
  118. type listenerInfo struct {
  119. port int // 0 means that no info about port is available
  120. }
  121. // Server is a HTTP/3 server.
  122. type Server struct {
  123. // Addr optionally specifies the UDP address for the server to listen on,
  124. // in the form "host:port".
  125. //
  126. // When used by ListenAndServe and ListenAndServeTLS methods, if empty,
  127. // ":https" (port 443) is used. See net.Dial for details of the address
  128. // format.
  129. //
  130. // Otherwise, if Port is not set and underlying QUIC listeners do not
  131. // have valid port numbers, the port part is used in Alt-Svc headers set
  132. // with SetQUICHeaders.
  133. Addr string
  134. // Port is used in Alt-Svc response headers set with SetQUICHeaders. If
  135. // needed Port can be manually set when the Server is created.
  136. //
  137. // This is useful when a Layer 4 firewall is redirecting UDP traffic and
  138. // clients must use a port different from the port the Server is
  139. // listening on.
  140. Port int
  141. // TLSConfig provides a TLS configuration for use by server. It must be
  142. // set for ListenAndServe and Serve methods.
  143. TLSConfig *tls.Config
  144. // QUICConfig provides the parameters for QUIC connection created with Serve.
  145. // If nil, it uses reasonable default values.
  146. //
  147. // Configured versions are also used in Alt-Svc response header set with SetQUICHeaders.
  148. QUICConfig *quic.Config
  149. // Handler is the HTTP request handler to use. If not set, defaults to
  150. // http.NotFound.
  151. Handler http.Handler
  152. // EnableDatagrams enables support for HTTP/3 datagrams (RFC 9297).
  153. // If set to true, QUICConfig.EnableDatagrams will be set.
  154. EnableDatagrams bool
  155. // MaxHeaderBytes controls the maximum number of bytes the server will
  156. // read parsing the request HEADERS frame. It does not limit the size of
  157. // the request body. If zero or negative, http.DefaultMaxHeaderBytes is
  158. // used.
  159. MaxHeaderBytes int
  160. // AdditionalSettings specifies additional HTTP/3 settings.
  161. // It is invalid to specify any settings defined by RFC 9114 (HTTP/3) and RFC 9297 (HTTP Datagrams).
  162. AdditionalSettings map[uint64]uint64
  163. // StreamHijacker, when set, is called for the first unknown frame parsed on a bidirectional stream.
  164. // It is called right after parsing the frame type.
  165. // If parsing the frame type fails, the error is passed to the callback.
  166. // In that case, the frame type will not be set.
  167. // Callers can either ignore the frame and return control of the stream back to HTTP/3
  168. // (by returning hijacked false).
  169. // Alternatively, callers can take over the QUIC stream (by returning hijacked true).
  170. StreamHijacker func(FrameType, quic.ConnectionTracingID, quic.Stream, error) (hijacked bool, err error)
  171. // UniStreamHijacker, when set, is called for unknown unidirectional stream of unknown stream type.
  172. // If parsing the stream type fails, the error is passed to the callback.
  173. // In that case, the stream type will not be set.
  174. UniStreamHijacker func(StreamType, quic.ConnectionTracingID, quic.ReceiveStream, error) (hijacked bool)
  175. // IdleTimeout specifies how long until idle clients connection should be
  176. // closed. Idle refers only to the HTTP/3 layer, activity at the QUIC layer
  177. // like PING frames are not considered.
  178. // If zero or negative, there is no timeout.
  179. IdleTimeout time.Duration
  180. // ConnContext optionally specifies a function that modifies the context used for a new connection c.
  181. // The provided ctx has a ServerContextKey value.
  182. ConnContext func(ctx context.Context, c quic.Connection) context.Context
  183. Logger *slog.Logger
  184. mutex sync.RWMutex
  185. listeners map[*QUICEarlyListener]listenerInfo
  186. closed bool
  187. closeCtx context.Context // canceled when the server is closed
  188. closeCancel context.CancelFunc // cancels the closeCtx
  189. graceCtx context.Context // canceled when the server is closed or gracefully closed
  190. graceCancel context.CancelFunc // cancels the graceCtx
  191. connCount atomic.Int64
  192. connHandlingDone chan struct{}
  193. altSvcHeader string
  194. }
  195. // ListenAndServe listens on the UDP address s.Addr and calls s.Handler to handle HTTP/3 requests on incoming connections.
  196. //
  197. // If s.Addr is blank, ":https" is used.
  198. func (s *Server) ListenAndServe() error {
  199. ln, err := s.setupListenerForConn(s.TLSConfig, nil)
  200. if err != nil {
  201. return err
  202. }
  203. defer s.removeListener(&ln)
  204. return s.serveListener(ln)
  205. }
  206. // ListenAndServeTLS listens on the UDP address s.Addr and calls s.Handler to handle HTTP/3 requests on incoming connections.
  207. //
  208. // If s.Addr is blank, ":https" is used.
  209. func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
  210. var err error
  211. certs := make([]tls.Certificate, 1)
  212. certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
  213. if err != nil {
  214. return err
  215. }
  216. // We currently only use the cert-related stuff from tls.Config,
  217. // so we don't need to make a full copy.
  218. ln, err := s.setupListenerForConn(&tls.Config{Certificates: certs}, nil)
  219. if err != nil {
  220. return err
  221. }
  222. defer s.removeListener(&ln)
  223. return s.serveListener(ln)
  224. }
  225. // Serve an existing UDP connection.
  226. // It is possible to reuse the same connection for outgoing connections.
  227. // Closing the server does not close the connection.
  228. func (s *Server) Serve(conn net.PacketConn) error {
  229. ln, err := s.setupListenerForConn(s.TLSConfig, conn)
  230. if err != nil {
  231. return err
  232. }
  233. defer s.removeListener(&ln)
  234. return s.serveListener(ln)
  235. }
  236. // init initializes the contexts used for shutting down the server.
  237. // It must be called with the mutex held.
  238. func (s *Server) init() {
  239. if s.closeCtx == nil {
  240. s.closeCtx, s.closeCancel = context.WithCancel(context.Background())
  241. s.graceCtx, s.graceCancel = context.WithCancel(s.closeCtx)
  242. }
  243. s.connHandlingDone = make(chan struct{}, 1)
  244. }
  245. func (s *Server) decreaseConnCount() {
  246. if s.connCount.Add(-1) == 0 && s.graceCtx.Err() != nil {
  247. close(s.connHandlingDone)
  248. }
  249. }
  250. // ServeQUICConn serves a single QUIC connection.
  251. func (s *Server) ServeQUICConn(conn quic.Connection) error {
  252. s.mutex.Lock()
  253. s.init()
  254. s.mutex.Unlock()
  255. s.connCount.Add(1)
  256. defer s.decreaseConnCount()
  257. return s.handleConn(conn)
  258. }
  259. // ServeListener serves an existing QUIC listener.
  260. // Make sure you use http3.ConfigureTLSConfig to configure a tls.Config
  261. // and use it to construct a http3-friendly QUIC listener.
  262. // Closing the server does close the listener.
  263. // ServeListener always returns a non-nil error. After Shutdown or Close, the returned error is http.ErrServerClosed.
  264. func (s *Server) ServeListener(ln QUICEarlyListener) error {
  265. s.mutex.Lock()
  266. if err := s.addListener(&ln); err != nil {
  267. s.mutex.Unlock()
  268. return err
  269. }
  270. s.mutex.Unlock()
  271. defer s.removeListener(&ln)
  272. return s.serveListener(ln)
  273. }
  274. func (s *Server) serveListener(ln QUICEarlyListener) error {
  275. for {
  276. conn, err := ln.Accept(s.graceCtx)
  277. // server closed
  278. if errors.Is(err, quic.ErrServerClosed) || s.graceCtx.Err() != nil {
  279. return http.ErrServerClosed
  280. }
  281. if err != nil {
  282. return err
  283. }
  284. s.connCount.Add(1)
  285. go func() {
  286. defer s.decreaseConnCount()
  287. if err := s.handleConn(conn); err != nil {
  288. if s.Logger != nil {
  289. s.Logger.Debug("handling connection failed", "error", err)
  290. }
  291. }
  292. }()
  293. }
  294. }
  295. var errServerWithoutTLSConfig = errors.New("use of http3.Server without TLSConfig")
  296. func (s *Server) setupListenerForConn(tlsConf *tls.Config, conn net.PacketConn) (QUICEarlyListener, error) {
  297. if tlsConf == nil {
  298. return nil, errServerWithoutTLSConfig
  299. }
  300. baseConf := ConfigureTLSConfig(tlsConf)
  301. quicConf := s.QUICConfig
  302. if quicConf == nil {
  303. quicConf = &quic.Config{Allow0RTT: true}
  304. } else {
  305. quicConf = s.QUICConfig.Clone()
  306. }
  307. if s.EnableDatagrams {
  308. quicConf.EnableDatagrams = true
  309. }
  310. s.mutex.Lock()
  311. defer s.mutex.Unlock()
  312. closed := s.closed
  313. if closed {
  314. return nil, http.ErrServerClosed
  315. }
  316. var ln QUICEarlyListener
  317. var err error
  318. if conn == nil {
  319. addr := s.Addr
  320. if addr == "" {
  321. addr = ":https"
  322. }
  323. ln, err = quicListenAddr(addr, baseConf, quicConf)
  324. } else {
  325. ln, err = quicListen(conn, baseConf, quicConf)
  326. }
  327. if err != nil {
  328. return nil, err
  329. }
  330. if err := s.addListener(&ln); err != nil {
  331. return nil, err
  332. }
  333. return ln, nil
  334. }
  335. func extractPort(addr string) (int, error) {
  336. _, portStr, err := net.SplitHostPort(addr)
  337. if err != nil {
  338. return 0, err
  339. }
  340. portInt, err := net.LookupPort("tcp", portStr)
  341. if err != nil {
  342. return 0, err
  343. }
  344. return portInt, nil
  345. }
  346. func (s *Server) generateAltSvcHeader() {
  347. if len(s.listeners) == 0 {
  348. // Don't announce any ports since no one is listening for connections
  349. s.altSvcHeader = ""
  350. return
  351. }
  352. // This code assumes that we will use protocol.SupportedVersions if no quic.Config is passed.
  353. supportedVersions := protocol.SupportedVersions
  354. if s.QUICConfig != nil && len(s.QUICConfig.Versions) > 0 {
  355. supportedVersions = s.QUICConfig.Versions
  356. }
  357. // keep track of which have been seen so we don't yield duplicate values
  358. seen := make(map[string]struct{}, len(supportedVersions))
  359. var versionStrings []string
  360. for _, version := range supportedVersions {
  361. if v := versionToALPN(version); len(v) > 0 {
  362. if _, ok := seen[v]; !ok {
  363. versionStrings = append(versionStrings, v)
  364. seen[v] = struct{}{}
  365. }
  366. }
  367. }
  368. var altSvc []string
  369. addPort := func(port int) {
  370. for _, v := range versionStrings {
  371. altSvc = append(altSvc, fmt.Sprintf(`%s=":%d"; ma=2592000`, v, port))
  372. }
  373. }
  374. if s.Port != 0 {
  375. // if Port is specified, we must use it instead of the
  376. // listener addresses since there's a reason it's specified.
  377. addPort(s.Port)
  378. } else {
  379. // if we have some listeners assigned, try to find ports
  380. // which we can announce, otherwise nothing should be announced
  381. validPortsFound := false
  382. for _, info := range s.listeners {
  383. if info.port != 0 {
  384. addPort(info.port)
  385. validPortsFound = true
  386. }
  387. }
  388. if !validPortsFound {
  389. if port, err := extractPort(s.Addr); err == nil {
  390. addPort(port)
  391. }
  392. }
  393. }
  394. s.altSvcHeader = strings.Join(altSvc, ",")
  395. }
  396. // We store a pointer to interface in the map set. This is safe because we only
  397. // call trackListener via Serve and can track+defer untrack the same pointer to
  398. // local variable there. We never need to compare a Listener from another caller.
  399. func (s *Server) addListener(l *QUICEarlyListener) error {
  400. if s.closed {
  401. return http.ErrServerClosed
  402. }
  403. if s.listeners == nil {
  404. s.listeners = make(map[*QUICEarlyListener]listenerInfo)
  405. }
  406. s.init()
  407. laddr := (*l).Addr()
  408. if port, err := extractPort(laddr.String()); err == nil {
  409. s.listeners[l] = listenerInfo{port}
  410. } else {
  411. logger := s.Logger
  412. if logger == nil {
  413. logger = slog.Default()
  414. }
  415. logger.Error("Unable to extract port from listener, will not be announced using SetQUICHeaders", "local addr", laddr, "error", err)
  416. s.listeners[l] = listenerInfo{}
  417. }
  418. s.generateAltSvcHeader()
  419. return nil
  420. }
  421. func (s *Server) removeListener(l *QUICEarlyListener) {
  422. s.mutex.Lock()
  423. defer s.mutex.Unlock()
  424. delete(s.listeners, l)
  425. s.generateAltSvcHeader()
  426. }
  427. // handleConn handles the HTTP/3 exchange on a QUIC connection.
  428. // It blocks until all HTTP handlers for all streams have returned.
  429. func (s *Server) handleConn(conn quic.Connection) error {
  430. // open the control stream and send a SETTINGS frame, it's also used to send a GOAWAY frame later
  431. // when the server is gracefully closed
  432. ctrlStr, err := conn.OpenUniStream()
  433. if err != nil {
  434. return fmt.Errorf("opening the control stream failed: %w", err)
  435. }
  436. b := make([]byte, 0, 64)
  437. b = quicvarint.Append(b, streamTypeControlStream) // stream type
  438. b = (&settingsFrame{
  439. Datagram: s.EnableDatagrams,
  440. ExtendedConnect: true,
  441. Other: s.AdditionalSettings,
  442. }).Append(b)
  443. ctrlStr.Write(b)
  444. ctx := conn.Context()
  445. ctx = context.WithValue(ctx, ServerContextKey, s)
  446. ctx = context.WithValue(ctx, http.LocalAddrContextKey, conn.LocalAddr())
  447. ctx = context.WithValue(ctx, RemoteAddrContextKey, conn.RemoteAddr())
  448. if s.ConnContext != nil {
  449. ctx = s.ConnContext(ctx, conn)
  450. if ctx == nil {
  451. panic("http3: ConnContext returned nil")
  452. }
  453. }
  454. hconn := newConnection(
  455. ctx,
  456. conn,
  457. s.EnableDatagrams,
  458. protocol.PerspectiveServer,
  459. s.Logger,
  460. s.IdleTimeout,
  461. )
  462. go hconn.handleUnidirectionalStreams(s.UniStreamHijacker)
  463. var nextStreamID quic.StreamID
  464. var wg sync.WaitGroup
  465. var handleErr error
  466. // Process all requests immediately.
  467. // It's the client's responsibility to decide which requests are eligible for 0-RTT.
  468. for {
  469. str, datagrams, err := hconn.acceptStream(s.graceCtx)
  470. if err != nil {
  471. // server (not gracefully) closed, close the connection immediately
  472. if s.closeCtx.Err() != nil {
  473. conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeNoError), "")
  474. handleErr = http.ErrServerClosed
  475. break
  476. }
  477. // gracefully closed, send GOAWAY frame and wait for requests to complete or grace period to end
  478. // new requests will be rejected and shouldn't be sent
  479. if s.graceCtx.Err() != nil {
  480. b = (&goAwayFrame{StreamID: nextStreamID}).Append(b[:0])
  481. // set a deadline to send the GOAWAY frame
  482. ctrlStr.SetWriteDeadline(time.Now().Add(goawayTimeout))
  483. ctrlStr.Write(b)
  484. select {
  485. case <-hconn.Context().Done():
  486. // we expect the client to eventually close the connection after receiving the GOAWAY
  487. case <-s.closeCtx.Done():
  488. // close the connection after graceful period
  489. conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeNoError), "")
  490. }
  491. handleErr = http.ErrServerClosed
  492. break
  493. }
  494. var appErr *quic.ApplicationError
  495. if !errors.As(err, &appErr) || appErr.ErrorCode != quic.ApplicationErrorCode(ErrCodeNoError) {
  496. handleErr = fmt.Errorf("accepting stream failed: %w", err)
  497. }
  498. break
  499. }
  500. nextStreamID = str.StreamID() + 4
  501. wg.Add(1)
  502. go func() {
  503. // handleRequest will return once the request has been handled,
  504. // or the underlying connection is closed
  505. defer wg.Done()
  506. s.handleRequest(hconn, str, datagrams, hconn.decoder)
  507. }()
  508. }
  509. wg.Wait()
  510. return handleErr
  511. }
  512. func (s *Server) maxHeaderBytes() uint64 {
  513. if s.MaxHeaderBytes <= 0 {
  514. return http.DefaultMaxHeaderBytes
  515. }
  516. return uint64(s.MaxHeaderBytes)
  517. }
  518. func (s *Server) handleRequest(conn *connection, str quic.Stream, datagrams *datagrammer, decoder *qpack.Decoder) {
  519. var ufh unknownFrameHandlerFunc
  520. if s.StreamHijacker != nil {
  521. ufh = func(ft FrameType, e error) (processed bool, err error) {
  522. return s.StreamHijacker(
  523. ft,
  524. conn.Context().Value(quic.ConnectionTracingKey).(quic.ConnectionTracingID),
  525. str,
  526. e,
  527. )
  528. }
  529. }
  530. fp := &frameParser{conn: conn, r: str, unknownFrameHandler: ufh}
  531. frame, err := fp.ParseNext()
  532. if err != nil {
  533. if !errors.Is(err, errHijacked) {
  534. str.CancelRead(quic.StreamErrorCode(ErrCodeRequestIncomplete))
  535. str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestIncomplete))
  536. }
  537. return
  538. }
  539. hf, ok := frame.(*headersFrame)
  540. if !ok {
  541. conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "expected first frame to be a HEADERS frame")
  542. return
  543. }
  544. if hf.Length > s.maxHeaderBytes() {
  545. str.CancelRead(quic.StreamErrorCode(ErrCodeFrameError))
  546. str.CancelWrite(quic.StreamErrorCode(ErrCodeFrameError))
  547. return
  548. }
  549. headerBlock := make([]byte, hf.Length)
  550. if _, err := io.ReadFull(str, headerBlock); err != nil {
  551. str.CancelRead(quic.StreamErrorCode(ErrCodeRequestIncomplete))
  552. str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestIncomplete))
  553. return
  554. }
  555. hfs, err := decoder.DecodeFull(headerBlock)
  556. if err != nil {
  557. // TODO: use the right error code
  558. conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeGeneralProtocolError), "expected first frame to be a HEADERS frame")
  559. return
  560. }
  561. req, err := requestFromHeaders(hfs)
  562. if err != nil {
  563. str.CancelRead(quic.StreamErrorCode(ErrCodeMessageError))
  564. str.CancelWrite(quic.StreamErrorCode(ErrCodeMessageError))
  565. return
  566. }
  567. connState := conn.ConnectionState().TLS
  568. // [Psiphon]
  569. req.TLS = tls.UnsafeFromConnectionState(&connState)
  570. req.RemoteAddr = conn.RemoteAddr().String()
  571. // Check that the client doesn't send more data in DATA frames than indicated by the Content-Length header (if set).
  572. // See section 4.1.2 of RFC 9114.
  573. contentLength := int64(-1)
  574. if _, ok := req.Header["Content-Length"]; ok && req.ContentLength >= 0 {
  575. contentLength = req.ContentLength
  576. }
  577. hstr := newStream(str, conn, datagrams, nil)
  578. body := newRequestBody(hstr, contentLength, conn.Context(), conn.ReceivedSettings(), conn.Settings)
  579. req.Body = body
  580. if s.Logger != nil {
  581. s.Logger.Debug("handling request", "method", req.Method, "host", req.Host, "uri", req.RequestURI)
  582. }
  583. ctx, cancel := context.WithCancel(conn.Context())
  584. req = req.WithContext(ctx)
  585. context.AfterFunc(str.Context(), cancel)
  586. r := newResponseWriter(hstr, conn, req.Method == http.MethodHead, s.Logger)
  587. handler := s.Handler
  588. if handler == nil {
  589. handler = http.DefaultServeMux
  590. }
  591. // It's the client's responsibility to decide which requests are eligible for 0-RTT.
  592. var panicked bool
  593. func() {
  594. defer func() {
  595. if p := recover(); p != nil {
  596. panicked = true
  597. if p == http.ErrAbortHandler {
  598. return
  599. }
  600. // Copied from net/http/server.go
  601. const size = 64 << 10
  602. buf := make([]byte, size)
  603. buf = buf[:runtime.Stack(buf, false)]
  604. logger := s.Logger
  605. if logger == nil {
  606. logger = slog.Default()
  607. }
  608. logger.Error("http: panic serving", "arg", p, "trace", string(buf))
  609. }
  610. }()
  611. handler.ServeHTTP(r, req)
  612. }()
  613. if r.wasStreamHijacked() {
  614. return
  615. }
  616. // only write response when there is no panic
  617. if !panicked {
  618. // response not written to the client yet, set Content-Length
  619. if !r.headerWritten {
  620. if _, haveCL := r.header["Content-Length"]; !haveCL {
  621. r.header.Set("Content-Length", strconv.FormatInt(r.numWritten, 10))
  622. }
  623. }
  624. r.Flush()
  625. r.flushTrailers()
  626. }
  627. // abort the stream when there is a panic
  628. if panicked {
  629. str.CancelRead(quic.StreamErrorCode(ErrCodeInternalError))
  630. str.CancelWrite(quic.StreamErrorCode(ErrCodeInternalError))
  631. return
  632. }
  633. // If the EOF was read by the handler, CancelRead() is a no-op.
  634. str.CancelRead(quic.StreamErrorCode(ErrCodeNoError))
  635. str.Close()
  636. }
  637. // Close the server immediately, aborting requests and sending CONNECTION_CLOSE frames to connected clients.
  638. // Close in combination with ListenAndServe() (instead of Serve()) may race if it is called before a UDP socket is established.
  639. // It is the caller's responsibility to close any connection passed to ServeQUICConn.
  640. func (s *Server) Close() error {
  641. s.mutex.Lock()
  642. defer s.mutex.Unlock()
  643. s.closed = true
  644. // server is never used
  645. if s.closeCtx == nil {
  646. return nil
  647. }
  648. s.closeCancel()
  649. var err error
  650. for ln := range s.listeners {
  651. if cerr := (*ln).Close(); cerr != nil && err == nil {
  652. err = cerr
  653. }
  654. }
  655. if s.connCount.Load() == 0 {
  656. return err
  657. }
  658. // wait for all connections to be closed
  659. <-s.connHandlingDone
  660. return err
  661. }
  662. // Shutdown shuts down the server gracefully.
  663. // The server sends a GOAWAY frame first, then or for all running requests to complete.
  664. // Shutdown in combination with ListenAndServe() (instead of Serve()) may race if it is called before a UDP socket is established.
  665. func (s *Server) Shutdown(ctx context.Context) error {
  666. s.mutex.Lock()
  667. s.closed = true
  668. // server is never used
  669. if s.closeCtx == nil {
  670. s.mutex.Unlock()
  671. return nil
  672. }
  673. s.graceCancel()
  674. s.mutex.Unlock()
  675. if s.connCount.Load() == 0 {
  676. return s.Close()
  677. }
  678. select {
  679. case <-s.connHandlingDone: // all connections were closed
  680. // When receiving a GOAWAY frame, HTTP/3 clients are expected to close the connection
  681. // once all requests were successfully handled...
  682. return s.Close()
  683. case <-ctx.Done():
  684. // ... however, clients handling long-lived requests (and misbehaving clients),
  685. // might not do so before the context is cancelled.
  686. // In this case, we close the server, which closes all existing connections
  687. // (expect those passed to ServeQUICConn).
  688. _ = s.Close()
  689. return ctx.Err()
  690. }
  691. }
  692. // ErrNoAltSvcPort is the error returned by SetQUICHeaders when no port was found
  693. // for Alt-Svc to announce. This can happen if listening on a PacketConn without a port
  694. // (UNIX socket, for example) and no port is specified in Server.Port or Server.Addr.
  695. var ErrNoAltSvcPort = errors.New("no port can be announced, specify it explicitly using Server.Port or Server.Addr")
  696. // SetQUICHeaders can be used to set the proper headers that announce that this server supports HTTP/3.
  697. // The values set by default advertise all the ports the server is listening on, but can be
  698. // changed to a specific port by setting Server.Port before launching the server.
  699. // If no listener's Addr().String() returns an address with a valid port, Server.Addr will be used
  700. // to extract the port, if specified.
  701. // For example, a server launched using ListenAndServe on an address with port 443 would set:
  702. //
  703. // Alt-Svc: h3=":443"; ma=2592000
  704. func (s *Server) SetQUICHeaders(hdr http.Header) error {
  705. s.mutex.RLock()
  706. defer s.mutex.RUnlock()
  707. if s.altSvcHeader == "" {
  708. return ErrNoAltSvcPort
  709. }
  710. // use the map directly to avoid constant canonicalization since the key is already canonicalized
  711. hdr["Alt-Svc"] = append(hdr["Alt-Svc"], s.altSvcHeader)
  712. return nil
  713. }
  714. // ListenAndServeQUIC listens on the UDP network address addr and calls the
  715. // handler for HTTP/3 requests on incoming connections. http.DefaultServeMux is
  716. // used when handler is nil.
  717. func ListenAndServeQUIC(addr, certFile, keyFile string, handler http.Handler) error {
  718. server := &Server{
  719. Addr: addr,
  720. Handler: handler,
  721. }
  722. return server.ListenAndServeTLS(certFile, keyFile)
  723. }
  724. // ListenAndServeTLS listens on the given network address for both TLS/TCP and QUIC
  725. // connections in parallel. It returns if one of the two returns an error.
  726. // http.DefaultServeMux is used when handler is nil.
  727. // The correct Alt-Svc headers for QUIC are set.
  728. func ListenAndServeTLS(addr, certFile, keyFile string, handler http.Handler) error {
  729. // Load certs
  730. var err error
  731. certs := make([]tls.Certificate, 1)
  732. certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
  733. if err != nil {
  734. return err
  735. }
  736. // We currently only use the cert-related stuff from tls.Config,
  737. // so we don't need to make a full copy.
  738. config := &tls.Config{
  739. Certificates: certs,
  740. }
  741. if addr == "" {
  742. addr = ":https"
  743. }
  744. // Open the listeners
  745. udpAddr, err := net.ResolveUDPAddr("udp", addr)
  746. if err != nil {
  747. return err
  748. }
  749. udpConn, err := net.ListenUDP("udp", udpAddr)
  750. if err != nil {
  751. return err
  752. }
  753. defer udpConn.Close()
  754. if handler == nil {
  755. handler = http.DefaultServeMux
  756. }
  757. // Start the servers
  758. quicServer := &Server{
  759. TLSConfig: config,
  760. Handler: handler,
  761. }
  762. hErr := make(chan error, 1)
  763. qErr := make(chan error, 1)
  764. go func() {
  765. hErr <- http.ListenAndServeTLS(addr, certFile, keyFile, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  766. quicServer.SetQUICHeaders(w.Header())
  767. handler.ServeHTTP(w, r)
  768. }))
  769. }()
  770. go func() {
  771. qErr <- quicServer.Serve(udpConn)
  772. }()
  773. select {
  774. case err := <-hErr:
  775. quicServer.Close()
  776. return err
  777. case err := <-qErr:
  778. // Cannot close the HTTP server or wait for requests to complete properly :/
  779. return err
  780. }
  781. }