]> git.feebdaed.xyz Git - 0xmirror/quic-go.git/commitdiff
http3: send GOAWAY frame in a new Goroutine (#5114)
authorMarten Seemann <martenseemann@gmail.com>
Sun, 4 May 2025 04:21:03 +0000 (12:21 +0800)
committerGitHub <noreply@github.com>
Sun, 4 May 2025 04:21:03 +0000 (06:21 +0200)
Sending might block if the peer didn't grant enough flow
control credit.

http3/server.go

index 96e7d6a346547e616f79bb4f4678c30c6d0e542d..88c255a933d5bce903ea22dabd39d10df5b9477c 100644 (file)
@@ -37,8 +37,6 @@ const (
        streamTypeQPACKDecoderStream = 3
 )
 
-const goawayTimeout = 5 * time.Second
-
 // A QUICEarlyListener listens for incoming QUIC connections.
 type QUICEarlyListener interface {
        Accept(context.Context) (quic.EarlyConnection, error)
@@ -491,10 +489,14 @@ func (s *Server) handleConn(conn quic.Connection) error {
                        // gracefully closed, send GOAWAY frame and wait for requests to complete or grace period to end
                        // new requests will be rejected and shouldn't be sent
                        if s.graceCtx.Err() != nil {
-                               b = (&goAwayFrame{StreamID: nextStreamID}).Append(b[:0])
-                               // set a deadline to send the GOAWAY frame
-                               ctrlStr.SetWriteDeadline(time.Now().Add(goawayTimeout))
-                               ctrlStr.Write(b)
+                               wg.Add(1)
+                               // Send the GOAWAY frame in a separate Goroutine.
+                               // Sending might block if the peer didn't grant enough flow control credit.
+                               // Write is guaranteed to return once the connection is closed.
+                               go func() {
+                                       defer wg.Done()
+                                       _, _ = ctrlStr.Write((&goAwayFrame{StreamID: nextStreamID}).Append(nil))
+                               }()
 
                                select {
                                case <-hconn.Context().Done():