google.golang.org/grpc@v1.74.2/internal/transport/http2_server.go (about)

     1  /*
     2   *
     3   * Copyright 2014 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package transport
    20  
    21  import (
    22  	"bytes"
    23  	"context"
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"math"
    28  	rand "math/rand/v2"
    29  	"net"
    30  	"net/http"
    31  	"strconv"
    32  	"sync"
    33  	"sync/atomic"
    34  	"time"
    35  
    36  	"golang.org/x/net/http2"
    37  	"golang.org/x/net/http2/hpack"
    38  	"google.golang.org/grpc/internal"
    39  	"google.golang.org/grpc/internal/grpclog"
    40  	"google.golang.org/grpc/internal/grpcutil"
    41  	"google.golang.org/grpc/internal/pretty"
    42  	istatus "google.golang.org/grpc/internal/status"
    43  	"google.golang.org/grpc/internal/syscall"
    44  	"google.golang.org/grpc/mem"
    45  	"google.golang.org/protobuf/proto"
    46  
    47  	"google.golang.org/grpc/codes"
    48  	"google.golang.org/grpc/credentials"
    49  	"google.golang.org/grpc/internal/channelz"
    50  	"google.golang.org/grpc/internal/grpcsync"
    51  	"google.golang.org/grpc/keepalive"
    52  	"google.golang.org/grpc/metadata"
    53  	"google.golang.org/grpc/peer"
    54  	"google.golang.org/grpc/stats"
    55  	"google.golang.org/grpc/status"
    56  	"google.golang.org/grpc/tap"
    57  )
    58  
    59  var (
    60  	// ErrIllegalHeaderWrite indicates that setting header is illegal because of
    61  	// the stream's state.
    62  	ErrIllegalHeaderWrite = status.Error(codes.Internal, "transport: SendHeader called multiple times")
    63  	// ErrHeaderListSizeLimitViolation indicates that the header list size is larger
    64  	// than the limit set by peer.
    65  	ErrHeaderListSizeLimitViolation = status.Error(codes.Internal, "transport: trying to send header list size larger than the limit set by peer")
    66  )
    67  
    68  // serverConnectionCounter counts the number of connections a server has seen
    69  // (equal to the number of http2Servers created). Must be accessed atomically.
    70  var serverConnectionCounter uint64
    71  
    72  // http2Server implements the ServerTransport interface with HTTP2.
    73  type http2Server struct {
    74  	lastRead        int64 // Keep this field 64-bit aligned. Accessed atomically.
    75  	done            chan struct{}
    76  	conn            net.Conn
    77  	loopy           *loopyWriter
    78  	readerDone      chan struct{} // sync point to enable testing.
    79  	loopyWriterDone chan struct{}
    80  	peer            peer.Peer
    81  	inTapHandle     tap.ServerInHandle
    82  	framer          *framer
    83  	// The max number of concurrent streams.
    84  	maxStreams uint32
    85  	// controlBuf delivers all the control related tasks (e.g., window
    86  	// updates, reset streams, and various settings) to the controller.
    87  	controlBuf *controlBuffer
    88  	fc         *trInFlow
    89  	stats      []stats.Handler
    90  	// Keepalive and max-age parameters for the server.
    91  	kp keepalive.ServerParameters
    92  	// Keepalive enforcement policy.
    93  	kep keepalive.EnforcementPolicy
    94  	// The time instance last ping was received.
    95  	lastPingAt time.Time
    96  	// Number of times the client has violated keepalive ping policy so far.
    97  	pingStrikes uint8
    98  	// Flag to signify that number of ping strikes should be reset to 0.
    99  	// This is set whenever data or header frames are sent.
   100  	// 1 means yes.
   101  	resetPingStrikes      uint32 // Accessed atomically.
   102  	initialWindowSize     int32
   103  	bdpEst                *bdpEstimator
   104  	maxSendHeaderListSize *uint32
   105  
   106  	mu sync.Mutex // guard the following
   107  
   108  	// drainEvent is initialized when Drain() is called the first time. After
   109  	// which the server writes out the first GoAway(with ID 2^31-1) frame. Then
   110  	// an independent goroutine will be launched to later send the second
   111  	// GoAway. During this time we don't want to write another first GoAway(with
   112  	// ID 2^31 -1) frame. Thus call to Drain() will be a no-op if drainEvent is
   113  	// already initialized since draining is already underway.
   114  	drainEvent    *grpcsync.Event
   115  	state         transportState
   116  	activeStreams map[uint32]*ServerStream
   117  	// idle is the time instant when the connection went idle.
   118  	// This is either the beginning of the connection or when the number of
   119  	// RPCs go down to 0.
   120  	// When the connection is busy, this value is set to 0.
   121  	idle time.Time
   122  
   123  	// Fields below are for channelz metric collection.
   124  	channelz   *channelz.Socket
   125  	bufferPool mem.BufferPool
   126  
   127  	connectionID uint64
   128  
   129  	// maxStreamMu guards the maximum stream ID
   130  	// This lock may not be taken if mu is already held.
   131  	maxStreamMu sync.Mutex
   132  	maxStreamID uint32 // max stream ID ever seen
   133  
   134  	logger *grpclog.PrefixLogger
   135  	// setResetPingStrikes is stored as a closure instead of making this a
   136  	// method on http2Server to avoid a heap allocation when converting a method
   137  	// to a closure for passing to frames objects.
   138  	setResetPingStrikes func()
   139  }
   140  
   141  // NewServerTransport creates a http2 transport with conn and configuration
   142  // options from config.
   143  //
   144  // It returns a non-nil transport and a nil error on success. On failure, it
   145  // returns a nil transport and a non-nil error. For a special case where the
   146  // underlying conn gets closed before the client preface could be read, it
   147  // returns a nil transport and a nil error.
   148  func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) {
   149  	var authInfo credentials.AuthInfo
   150  	rawConn := conn
   151  	if config.Credentials != nil {
   152  		var err error
   153  		conn, authInfo, err = config.Credentials.ServerHandshake(rawConn)
   154  		if err != nil {
   155  			// ErrConnDispatched means that the connection was dispatched away
   156  			// from gRPC; those connections should be left open. io.EOF means
   157  			// the connection was closed before handshaking completed, which can
   158  			// happen naturally from probers. Return these errors directly.
   159  			if err == credentials.ErrConnDispatched || err == io.EOF {
   160  				return nil, err
   161  			}
   162  			return nil, connectionErrorf(false, err, "ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
   163  		}
   164  	}
   165  	writeBufSize := config.WriteBufferSize
   166  	readBufSize := config.ReadBufferSize
   167  	maxHeaderListSize := defaultServerMaxHeaderListSize
   168  	if config.MaxHeaderListSize != nil {
   169  		maxHeaderListSize = *config.MaxHeaderListSize
   170  	}
   171  	framer := newFramer(conn, writeBufSize, readBufSize, config.SharedWriteBuffer, maxHeaderListSize)
   172  	// Send initial settings as connection preface to client.
   173  	isettings := []http2.Setting{{
   174  		ID:  http2.SettingMaxFrameSize,
   175  		Val: http2MaxFrameLen,
   176  	}}
   177  	if config.MaxStreams != math.MaxUint32 {
   178  		isettings = append(isettings, http2.Setting{
   179  			ID:  http2.SettingMaxConcurrentStreams,
   180  			Val: config.MaxStreams,
   181  		})
   182  	}
   183  	iwz := int32(initialWindowSize)
   184  	if config.InitialWindowSize >= defaultWindowSize {
   185  		iwz = config.InitialWindowSize
   186  	}
   187  	icwz := int32(initialWindowSize)
   188  	if config.InitialConnWindowSize >= defaultWindowSize {
   189  		icwz = config.InitialConnWindowSize
   190  	}
   191  	if iwz != defaultWindowSize {
   192  		isettings = append(isettings, http2.Setting{
   193  			ID:  http2.SettingInitialWindowSize,
   194  			Val: uint32(iwz)})
   195  	}
   196  	if config.MaxHeaderListSize != nil {
   197  		isettings = append(isettings, http2.Setting{
   198  			ID:  http2.SettingMaxHeaderListSize,
   199  			Val: *config.MaxHeaderListSize,
   200  		})
   201  	}
   202  	if config.HeaderTableSize != nil {
   203  		isettings = append(isettings, http2.Setting{
   204  			ID:  http2.SettingHeaderTableSize,
   205  			Val: *config.HeaderTableSize,
   206  		})
   207  	}
   208  	if err := framer.fr.WriteSettings(isettings...); err != nil {
   209  		return nil, connectionErrorf(false, err, "transport: %v", err)
   210  	}
   211  	// Adjust the connection flow control window if needed.
   212  	if delta := uint32(icwz - defaultWindowSize); delta > 0 {
   213  		if err := framer.fr.WriteWindowUpdate(0, delta); err != nil {
   214  			return nil, connectionErrorf(false, err, "transport: %v", err)
   215  		}
   216  	}
   217  	kp := config.KeepaliveParams
   218  	if kp.MaxConnectionIdle == 0 {
   219  		kp.MaxConnectionIdle = defaultMaxConnectionIdle
   220  	}
   221  	if kp.MaxConnectionAge == 0 {
   222  		kp.MaxConnectionAge = defaultMaxConnectionAge
   223  	}
   224  	// Add a jitter to MaxConnectionAge.
   225  	kp.MaxConnectionAge += getJitter(kp.MaxConnectionAge)
   226  	if kp.MaxConnectionAgeGrace == 0 {
   227  		kp.MaxConnectionAgeGrace = defaultMaxConnectionAgeGrace
   228  	}
   229  	if kp.Time == 0 {
   230  		kp.Time = defaultServerKeepaliveTime
   231  	}
   232  	if kp.Timeout == 0 {
   233  		kp.Timeout = defaultServerKeepaliveTimeout
   234  	}
   235  	if kp.Time != infinity {
   236  		if err = syscall.SetTCPUserTimeout(rawConn, kp.Timeout); err != nil {
   237  			return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err)
   238  		}
   239  	}
   240  	kep := config.KeepalivePolicy
   241  	if kep.MinTime == 0 {
   242  		kep.MinTime = defaultKeepalivePolicyMinTime
   243  	}
   244  
   245  	done := make(chan struct{})
   246  	peer := peer.Peer{
   247  		Addr:      conn.RemoteAddr(),
   248  		LocalAddr: conn.LocalAddr(),
   249  		AuthInfo:  authInfo,
   250  	}
   251  	t := &http2Server{
   252  		done:              done,
   253  		conn:              conn,
   254  		peer:              peer,
   255  		framer:            framer,
   256  		readerDone:        make(chan struct{}),
   257  		loopyWriterDone:   make(chan struct{}),
   258  		maxStreams:        config.MaxStreams,
   259  		inTapHandle:       config.InTapHandle,
   260  		fc:                &trInFlow{limit: uint32(icwz)},
   261  		state:             reachable,
   262  		activeStreams:     make(map[uint32]*ServerStream),
   263  		stats:             config.StatsHandlers,
   264  		kp:                kp,
   265  		idle:              time.Now(),
   266  		kep:               kep,
   267  		initialWindowSize: iwz,
   268  		bufferPool:        config.BufferPool,
   269  	}
   270  	t.setResetPingStrikes = func() {
   271  		atomic.StoreUint32(&t.resetPingStrikes, 1)
   272  	}
   273  	var czSecurity credentials.ChannelzSecurityValue
   274  	if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok {
   275  		czSecurity = au.GetSecurityValue()
   276  	}
   277  	t.channelz = channelz.RegisterSocket(
   278  		&channelz.Socket{
   279  			SocketType:       channelz.SocketTypeNormal,
   280  			Parent:           config.ChannelzParent,
   281  			SocketMetrics:    channelz.SocketMetrics{},
   282  			EphemeralMetrics: t.socketMetrics,
   283  			LocalAddr:        t.peer.LocalAddr,
   284  			RemoteAddr:       t.peer.Addr,
   285  			SocketOptions:    channelz.GetSocketOption(t.conn),
   286  			Security:         czSecurity,
   287  		},
   288  	)
   289  	t.logger = prefixLoggerForServerTransport(t)
   290  
   291  	t.controlBuf = newControlBuffer(t.done)
   292  	if !config.StaticWindowSize {
   293  		t.bdpEst = &bdpEstimator{
   294  			bdp:               initialWindowSize,
   295  			updateFlowControl: t.updateFlowControl,
   296  		}
   297  	}
   298  
   299  	t.connectionID = atomic.AddUint64(&serverConnectionCounter, 1)
   300  	t.framer.writer.Flush()
   301  
   302  	defer func() {
   303  		if err != nil {
   304  			t.Close(err)
   305  		}
   306  	}()
   307  
   308  	// Check the validity of client preface.
   309  	preface := make([]byte, len(clientPreface))
   310  	if _, err := io.ReadFull(t.conn, preface); err != nil {
   311  		// In deployments where a gRPC server runs behind a cloud load balancer
   312  		// which performs regular TCP level health checks, the connection is
   313  		// closed immediately by the latter.  Returning io.EOF here allows the
   314  		// grpc server implementation to recognize this scenario and suppress
   315  		// logging to reduce spam.
   316  		if err == io.EOF {
   317  			return nil, io.EOF
   318  		}
   319  		return nil, connectionErrorf(false, err, "transport: http2Server.HandleStreams failed to receive the preface from client: %v", err)
   320  	}
   321  	if !bytes.Equal(preface, clientPreface) {
   322  		return nil, connectionErrorf(false, nil, "transport: http2Server.HandleStreams received bogus greeting from client: %q", preface)
   323  	}
   324  
   325  	frame, err := t.framer.fr.ReadFrame()
   326  	if err == io.EOF || err == io.ErrUnexpectedEOF {
   327  		return nil, err
   328  	}
   329  	if err != nil {
   330  		return nil, connectionErrorf(false, err, "transport: http2Server.HandleStreams failed to read initial settings frame: %v", err)
   331  	}
   332  	atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
   333  	sf, ok := frame.(*http2.SettingsFrame)
   334  	if !ok {
   335  		return nil, connectionErrorf(false, nil, "transport: http2Server.HandleStreams saw invalid preface type %T from client", frame)
   336  	}
   337  	t.handleSettings(sf)
   338  
   339  	go func() {
   340  		t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler, t.bufferPool)
   341  		err := t.loopy.run()
   342  		close(t.loopyWriterDone)
   343  		if !isIOError(err) {
   344  			// Close the connection if a non-I/O error occurs (for I/O errors
   345  			// the reader will also encounter the error and close).  Wait 1
   346  			// second before closing the connection, or when the reader is done
   347  			// (i.e. the client already closed the connection or a connection
   348  			// error occurred).  This avoids the potential problem where there
   349  			// is unread data on the receive side of the connection, which, if
   350  			// closed, would lead to a TCP RST instead of FIN, and the client
   351  			// encountering errors.  For more info:
   352  			// https://github.com/grpc/grpc-go/issues/5358
   353  			timer := time.NewTimer(time.Second)
   354  			defer timer.Stop()
   355  			select {
   356  			case <-t.readerDone:
   357  			case <-timer.C:
   358  			}
   359  			t.conn.Close()
   360  		}
   361  	}()
   362  	go t.keepalive()
   363  	return t, nil
   364  }
   365  
   366  // operateHeaders takes action on the decoded headers. Returns an error if fatal
   367  // error encountered and transport needs to close, otherwise returns nil.
   368  func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeadersFrame, handle func(*ServerStream)) error {
   369  	// Acquire max stream ID lock for entire duration
   370  	t.maxStreamMu.Lock()
   371  	defer t.maxStreamMu.Unlock()
   372  
   373  	streamID := frame.Header().StreamID
   374  
   375  	// frame.Truncated is set to true when framer detects that the current header
   376  	// list size hits MaxHeaderListSize limit.
   377  	if frame.Truncated {
   378  		t.controlBuf.put(&cleanupStream{
   379  			streamID: streamID,
   380  			rst:      true,
   381  			rstCode:  http2.ErrCodeFrameSize,
   382  			onWrite:  func() {},
   383  		})
   384  		return nil
   385  	}
   386  
   387  	if streamID%2 != 1 || streamID <= t.maxStreamID {
   388  		// illegal gRPC stream id.
   389  		return fmt.Errorf("received an illegal stream id: %v. headers frame: %+v", streamID, frame)
   390  	}
   391  	t.maxStreamID = streamID
   392  
   393  	buf := newRecvBuffer()
   394  	s := &ServerStream{
   395  		Stream: &Stream{
   396  			id:  streamID,
   397  			buf: buf,
   398  			fc:  &inFlow{limit: uint32(t.initialWindowSize)},
   399  		},
   400  		st:               t,
   401  		headerWireLength: int(frame.Header().Length),
   402  	}
   403  	var (
   404  		// if false, content-type was missing or invalid
   405  		isGRPC      = false
   406  		contentType = ""
   407  		mdata       = make(metadata.MD, len(frame.Fields))
   408  		httpMethod  string
   409  		// these are set if an error is encountered while parsing the headers
   410  		protocolError bool
   411  		headerError   *status.Status
   412  
   413  		timeoutSet bool
   414  		timeout    time.Duration
   415  	)
   416  
   417  	for _, hf := range frame.Fields {
   418  		switch hf.Name {
   419  		case "content-type":
   420  			contentSubtype, validContentType := grpcutil.ContentSubtype(hf.Value)
   421  			if !validContentType {
   422  				contentType = hf.Value
   423  				break
   424  			}
   425  			mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
   426  			s.contentSubtype = contentSubtype
   427  			isGRPC = true
   428  
   429  		case "grpc-accept-encoding":
   430  			mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
   431  			if hf.Value == "" {
   432  				continue
   433  			}
   434  			compressors := hf.Value
   435  			if s.clientAdvertisedCompressors != "" {
   436  				compressors = s.clientAdvertisedCompressors + "," + compressors
   437  			}
   438  			s.clientAdvertisedCompressors = compressors
   439  		case "grpc-encoding":
   440  			s.recvCompress = hf.Value
   441  		case ":method":
   442  			httpMethod = hf.Value
   443  		case ":path":
   444  			s.method = hf.Value
   445  		case "grpc-timeout":
   446  			timeoutSet = true
   447  			var err error
   448  			if timeout, err = decodeTimeout(hf.Value); err != nil {
   449  				headerError = status.Newf(codes.Internal, "malformed grpc-timeout: %v", err)
   450  			}
   451  		// "Transports must consider requests containing the Connection header
   452  		// as malformed." - A41
   453  		case "connection":
   454  			if t.logger.V(logLevel) {
   455  				t.logger.Infof("Received a HEADERS frame with a :connection header which makes the request malformed, as per the HTTP/2 spec")
   456  			}
   457  			protocolError = true
   458  		default:
   459  			if isReservedHeader(hf.Name) && !isWhitelistedHeader(hf.Name) {
   460  				break
   461  			}
   462  			v, err := decodeMetadataHeader(hf.Name, hf.Value)
   463  			if err != nil {
   464  				headerError = status.Newf(codes.Internal, "malformed binary metadata %q in header %q: %v", hf.Value, hf.Name, err)
   465  				t.logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
   466  				break
   467  			}
   468  			mdata[hf.Name] = append(mdata[hf.Name], v)
   469  		}
   470  	}
   471  
   472  	// "If multiple Host headers or multiple :authority headers are present, the
   473  	// request must be rejected with an HTTP status code 400 as required by Host
   474  	// validation in RFC 7230 ยง5.4, gRPC status code INTERNAL, or RST_STREAM
   475  	// with HTTP/2 error code PROTOCOL_ERROR." - A41. Since this is a HTTP/2
   476  	// error, this takes precedence over a client not speaking gRPC.
   477  	if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 {
   478  		errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"]))
   479  		if t.logger.V(logLevel) {
   480  			t.logger.Infof("Aborting the stream early: %v", errMsg)
   481  		}
   482  		t.controlBuf.put(&earlyAbortStream{
   483  			httpStatus:     http.StatusBadRequest,
   484  			streamID:       streamID,
   485  			contentSubtype: s.contentSubtype,
   486  			status:         status.New(codes.Internal, errMsg),
   487  			rst:            !frame.StreamEnded(),
   488  		})
   489  		return nil
   490  	}
   491  
   492  	if protocolError {
   493  		t.controlBuf.put(&cleanupStream{
   494  			streamID: streamID,
   495  			rst:      true,
   496  			rstCode:  http2.ErrCodeProtocol,
   497  			onWrite:  func() {},
   498  		})
   499  		return nil
   500  	}
   501  	if !isGRPC {
   502  		t.controlBuf.put(&earlyAbortStream{
   503  			httpStatus:     http.StatusUnsupportedMediaType,
   504  			streamID:       streamID,
   505  			contentSubtype: s.contentSubtype,
   506  			status:         status.Newf(codes.InvalidArgument, "invalid gRPC request content-type %q", contentType),
   507  			rst:            !frame.StreamEnded(),
   508  		})
   509  		return nil
   510  	}
   511  	if headerError != nil {
   512  		t.controlBuf.put(&earlyAbortStream{
   513  			httpStatus:     http.StatusBadRequest,
   514  			streamID:       streamID,
   515  			contentSubtype: s.contentSubtype,
   516  			status:         headerError,
   517  			rst:            !frame.StreamEnded(),
   518  		})
   519  		return nil
   520  	}
   521  
   522  	// "If :authority is missing, Host must be renamed to :authority." - A41
   523  	if len(mdata[":authority"]) == 0 {
   524  		// No-op if host isn't present, no eventual :authority header is a valid
   525  		// RPC.
   526  		if host, ok := mdata["host"]; ok {
   527  			mdata[":authority"] = host
   528  			delete(mdata, "host")
   529  		}
   530  	} else {
   531  		// "If :authority is present, Host must be discarded" - A41
   532  		delete(mdata, "host")
   533  	}
   534  
   535  	if frame.StreamEnded() {
   536  		// s is just created by the caller. No lock needed.
   537  		s.state = streamReadDone
   538  	}
   539  	if timeoutSet {
   540  		s.ctx, s.cancel = context.WithTimeout(ctx, timeout)
   541  	} else {
   542  		s.ctx, s.cancel = context.WithCancel(ctx)
   543  	}
   544  
   545  	// Attach the received metadata to the context.
   546  	if len(mdata) > 0 {
   547  		s.ctx = metadata.NewIncomingContext(s.ctx, mdata)
   548  	}
   549  	t.mu.Lock()
   550  	if t.state != reachable {
   551  		t.mu.Unlock()
   552  		s.cancel()
   553  		return nil
   554  	}
   555  	if uint32(len(t.activeStreams)) >= t.maxStreams {
   556  		t.mu.Unlock()
   557  		t.controlBuf.put(&cleanupStream{
   558  			streamID: streamID,
   559  			rst:      true,
   560  			rstCode:  http2.ErrCodeRefusedStream,
   561  			onWrite:  func() {},
   562  		})
   563  		s.cancel()
   564  		return nil
   565  	}
   566  	if httpMethod != http.MethodPost {
   567  		t.mu.Unlock()
   568  		errMsg := fmt.Sprintf("Received a HEADERS frame with :method %q which should be POST", httpMethod)
   569  		if t.logger.V(logLevel) {
   570  			t.logger.Infof("Aborting the stream early: %v", errMsg)
   571  		}
   572  		t.controlBuf.put(&earlyAbortStream{
   573  			httpStatus:     http.StatusMethodNotAllowed,
   574  			streamID:       streamID,
   575  			contentSubtype: s.contentSubtype,
   576  			status:         status.New(codes.Internal, errMsg),
   577  			rst:            !frame.StreamEnded(),
   578  		})
   579  		s.cancel()
   580  		return nil
   581  	}
   582  	if t.inTapHandle != nil {
   583  		var err error
   584  		if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method, Header: mdata}); err != nil {
   585  			t.mu.Unlock()
   586  			if t.logger.V(logLevel) {
   587  				t.logger.Infof("Aborting the stream early due to InTapHandle failure: %v", err)
   588  			}
   589  			stat, ok := status.FromError(err)
   590  			if !ok {
   591  				stat = status.New(codes.PermissionDenied, err.Error())
   592  			}
   593  			t.controlBuf.put(&earlyAbortStream{
   594  				httpStatus:     http.StatusOK,
   595  				streamID:       s.id,
   596  				contentSubtype: s.contentSubtype,
   597  				status:         stat,
   598  				rst:            !frame.StreamEnded(),
   599  			})
   600  			return nil
   601  		}
   602  	}
   603  
   604  	if s.ctx.Err() != nil {
   605  		t.mu.Unlock()
   606  		// Early abort in case the timeout was zero or so low it already fired.
   607  		t.controlBuf.put(&earlyAbortStream{
   608  			httpStatus:     http.StatusOK,
   609  			streamID:       s.id,
   610  			contentSubtype: s.contentSubtype,
   611  			status:         status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()),
   612  			rst:            !frame.StreamEnded(),
   613  		})
   614  		return nil
   615  	}
   616  
   617  	t.activeStreams[streamID] = s
   618  	if len(t.activeStreams) == 1 {
   619  		t.idle = time.Time{}
   620  	}
   621  
   622  	// Start a timer to close the stream on reaching the deadline.
   623  	if timeoutSet {
   624  		// We need to wait for s.cancel to be updated before calling
   625  		// t.closeStream to avoid data races.
   626  		cancelUpdated := make(chan struct{})
   627  		timer := internal.TimeAfterFunc(timeout, func() {
   628  			<-cancelUpdated
   629  			t.closeStream(s, true, http2.ErrCodeCancel, false)
   630  		})
   631  		oldCancel := s.cancel
   632  		s.cancel = func() {
   633  			oldCancel()
   634  			timer.Stop()
   635  		}
   636  		close(cancelUpdated)
   637  	}
   638  	t.mu.Unlock()
   639  	if channelz.IsOn() {
   640  		t.channelz.SocketMetrics.StreamsStarted.Add(1)
   641  		t.channelz.SocketMetrics.LastRemoteStreamCreatedTimestamp.Store(time.Now().UnixNano())
   642  	}
   643  	s.requestRead = func(n int) {
   644  		t.adjustWindow(s, uint32(n))
   645  	}
   646  	s.ctxDone = s.ctx.Done()
   647  	s.wq = newWriteQuota(defaultWriteQuota, s.ctxDone)
   648  	s.trReader = &transportReader{
   649  		reader: &recvBufferReader{
   650  			ctx:     s.ctx,
   651  			ctxDone: s.ctxDone,
   652  			recv:    s.buf,
   653  		},
   654  		windowHandler: func(n int) {
   655  			t.updateWindow(s, uint32(n))
   656  		},
   657  	}
   658  	// Register the stream with loopy.
   659  	t.controlBuf.put(&registerStream{
   660  		streamID: s.id,
   661  		wq:       s.wq,
   662  	})
   663  	handle(s)
   664  	return nil
   665  }
   666  
   667  // HandleStreams receives incoming streams using the given handler. This is
   668  // typically run in a separate goroutine.
   669  // traceCtx attaches trace to ctx and returns the new context.
   670  func (t *http2Server) HandleStreams(ctx context.Context, handle func(*ServerStream)) {
   671  	defer func() {
   672  		close(t.readerDone)
   673  		<-t.loopyWriterDone
   674  	}()
   675  	for {
   676  		t.controlBuf.throttle()
   677  		frame, err := t.framer.fr.ReadFrame()
   678  		atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
   679  		if err != nil {
   680  			if se, ok := err.(http2.StreamError); ok {
   681  				if t.logger.V(logLevel) {
   682  					t.logger.Warningf("Encountered http2.StreamError: %v", se)
   683  				}
   684  				t.mu.Lock()
   685  				s := t.activeStreams[se.StreamID]
   686  				t.mu.Unlock()
   687  				if s != nil {
   688  					t.closeStream(s, true, se.Code, false)
   689  				} else {
   690  					t.controlBuf.put(&cleanupStream{
   691  						streamID: se.StreamID,
   692  						rst:      true,
   693  						rstCode:  se.Code,
   694  						onWrite:  func() {},
   695  					})
   696  				}
   697  				continue
   698  			}
   699  			t.Close(err)
   700  			return
   701  		}
   702  		switch frame := frame.(type) {
   703  		case *http2.MetaHeadersFrame:
   704  			if err := t.operateHeaders(ctx, frame, handle); err != nil {
   705  				// Any error processing client headers, e.g. invalid stream ID,
   706  				// is considered a protocol violation.
   707  				t.controlBuf.put(&goAway{
   708  					code:      http2.ErrCodeProtocol,
   709  					debugData: []byte(err.Error()),
   710  					closeConn: err,
   711  				})
   712  				continue
   713  			}
   714  		case *http2.DataFrame:
   715  			t.handleData(frame)
   716  		case *http2.RSTStreamFrame:
   717  			t.handleRSTStream(frame)
   718  		case *http2.SettingsFrame:
   719  			t.handleSettings(frame)
   720  		case *http2.PingFrame:
   721  			t.handlePing(frame)
   722  		case *http2.WindowUpdateFrame:
   723  			t.handleWindowUpdate(frame)
   724  		case *http2.GoAwayFrame:
   725  			// TODO: Handle GoAway from the client appropriately.
   726  		default:
   727  			if t.logger.V(logLevel) {
   728  				t.logger.Infof("Received unsupported frame type %T", frame)
   729  			}
   730  		}
   731  	}
   732  }
   733  
   734  func (t *http2Server) getStream(f http2.Frame) (*ServerStream, bool) {
   735  	t.mu.Lock()
   736  	defer t.mu.Unlock()
   737  	if t.activeStreams == nil {
   738  		// The transport is closing.
   739  		return nil, false
   740  	}
   741  	s, ok := t.activeStreams[f.Header().StreamID]
   742  	if !ok {
   743  		// The stream is already done.
   744  		return nil, false
   745  	}
   746  	return s, true
   747  }
   748  
   749  // adjustWindow sends out extra window update over the initial window size
   750  // of stream if the application is requesting data larger in size than
   751  // the window.
   752  func (t *http2Server) adjustWindow(s *ServerStream, n uint32) {
   753  	if w := s.fc.maybeAdjust(n); w > 0 {
   754  		t.controlBuf.put(&outgoingWindowUpdate{streamID: s.id, increment: w})
   755  	}
   756  
   757  }
   758  
   759  // updateWindow adjusts the inbound quota for the stream and the transport.
   760  // Window updates will deliver to the controller for sending when
   761  // the cumulative quota exceeds the corresponding threshold.
   762  func (t *http2Server) updateWindow(s *ServerStream, n uint32) {
   763  	if w := s.fc.onRead(n); w > 0 {
   764  		t.controlBuf.put(&outgoingWindowUpdate{streamID: s.id,
   765  			increment: w,
   766  		})
   767  	}
   768  }
   769  
   770  // updateFlowControl updates the incoming flow control windows
   771  // for the transport and the stream based on the current bdp
   772  // estimation.
   773  func (t *http2Server) updateFlowControl(n uint32) {
   774  	t.mu.Lock()
   775  	for _, s := range t.activeStreams {
   776  		s.fc.newLimit(n)
   777  	}
   778  	t.initialWindowSize = int32(n)
   779  	t.mu.Unlock()
   780  	t.controlBuf.put(&outgoingWindowUpdate{
   781  		streamID:  0,
   782  		increment: t.fc.newLimit(n),
   783  	})
   784  	t.controlBuf.put(&outgoingSettings{
   785  		ss: []http2.Setting{
   786  			{
   787  				ID:  http2.SettingInitialWindowSize,
   788  				Val: n,
   789  			},
   790  		},
   791  	})
   792  
   793  }
   794  
   795  func (t *http2Server) handleData(f *http2.DataFrame) {
   796  	size := f.Header().Length
   797  	var sendBDPPing bool
   798  	if t.bdpEst != nil {
   799  		sendBDPPing = t.bdpEst.add(size)
   800  	}
   801  	// Decouple connection's flow control from application's read.
   802  	// An update on connection's flow control should not depend on
   803  	// whether user application has read the data or not. Such a
   804  	// restriction is already imposed on the stream's flow control,
   805  	// and therefore the sender will be blocked anyways.
   806  	// Decoupling the connection flow control will prevent other
   807  	// active(fast) streams from starving in presence of slow or
   808  	// inactive streams.
   809  	if w := t.fc.onData(size); w > 0 {
   810  		t.controlBuf.put(&outgoingWindowUpdate{
   811  			streamID:  0,
   812  			increment: w,
   813  		})
   814  	}
   815  	if sendBDPPing {
   816  		// Avoid excessive ping detection (e.g. in an L7 proxy)
   817  		// by sending a window update prior to the BDP ping.
   818  		if w := t.fc.reset(); w > 0 {
   819  			t.controlBuf.put(&outgoingWindowUpdate{
   820  				streamID:  0,
   821  				increment: w,
   822  			})
   823  		}
   824  		t.controlBuf.put(bdpPing)
   825  	}
   826  	// Select the right stream to dispatch.
   827  	s, ok := t.getStream(f)
   828  	if !ok {
   829  		return
   830  	}
   831  	if s.getState() == streamReadDone {
   832  		t.closeStream(s, true, http2.ErrCodeStreamClosed, false)
   833  		return
   834  	}
   835  	if size > 0 {
   836  		if err := s.fc.onData(size); err != nil {
   837  			t.closeStream(s, true, http2.ErrCodeFlowControl, false)
   838  			return
   839  		}
   840  		if f.Header().Flags.Has(http2.FlagDataPadded) {
   841  			if w := s.fc.onRead(size - uint32(len(f.Data()))); w > 0 {
   842  				t.controlBuf.put(&outgoingWindowUpdate{s.id, w})
   843  			}
   844  		}
   845  		// TODO(bradfitz, zhaoq): A copy is required here because there is no
   846  		// guarantee f.Data() is consumed before the arrival of next frame.
   847  		// Can this copy be eliminated?
   848  		if len(f.Data()) > 0 {
   849  			pool := t.bufferPool
   850  			if pool == nil {
   851  				// Note that this is only supposed to be nil in tests. Otherwise, stream is
   852  				// always initialized with a BufferPool.
   853  				pool = mem.DefaultBufferPool()
   854  			}
   855  			s.write(recvMsg{buffer: mem.Copy(f.Data(), pool)})
   856  		}
   857  	}
   858  	if f.StreamEnded() {
   859  		// Received the end of stream from the client.
   860  		s.compareAndSwapState(streamActive, streamReadDone)
   861  		s.write(recvMsg{err: io.EOF})
   862  	}
   863  }
   864  
   865  func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) {
   866  	// If the stream is not deleted from the transport's active streams map, then do a regular close stream.
   867  	if s, ok := t.getStream(f); ok {
   868  		t.closeStream(s, false, 0, false)
   869  		return
   870  	}
   871  	// If the stream is already deleted from the active streams map, then put a cleanupStream item into controlbuf to delete the stream from loopy writer's established streams map.
   872  	t.controlBuf.put(&cleanupStream{
   873  		streamID: f.Header().StreamID,
   874  		rst:      false,
   875  		rstCode:  0,
   876  		onWrite:  func() {},
   877  	})
   878  }
   879  
   880  func (t *http2Server) handleSettings(f *http2.SettingsFrame) {
   881  	if f.IsAck() {
   882  		return
   883  	}
   884  	var ss []http2.Setting
   885  	var updateFuncs []func()
   886  	f.ForeachSetting(func(s http2.Setting) error {
   887  		switch s.ID {
   888  		case http2.SettingMaxHeaderListSize:
   889  			updateFuncs = append(updateFuncs, func() {
   890  				t.maxSendHeaderListSize = new(uint32)
   891  				*t.maxSendHeaderListSize = s.Val
   892  			})
   893  		default:
   894  			ss = append(ss, s)
   895  		}
   896  		return nil
   897  	})
   898  	t.controlBuf.executeAndPut(func() bool {
   899  		for _, f := range updateFuncs {
   900  			f()
   901  		}
   902  		return true
   903  	}, &incomingSettings{
   904  		ss: ss,
   905  	})
   906  }
   907  
   908  const (
   909  	maxPingStrikes     = 2
   910  	defaultPingTimeout = 2 * time.Hour
   911  )
   912  
   913  func (t *http2Server) handlePing(f *http2.PingFrame) {
   914  	if f.IsAck() {
   915  		if f.Data == goAwayPing.data && t.drainEvent != nil {
   916  			t.drainEvent.Fire()
   917  			return
   918  		}
   919  		// Maybe it's a BDP ping.
   920  		if t.bdpEst != nil {
   921  			t.bdpEst.calculate(f.Data)
   922  		}
   923  		return
   924  	}
   925  	pingAck := &ping{ack: true}
   926  	copy(pingAck.data[:], f.Data[:])
   927  	t.controlBuf.put(pingAck)
   928  
   929  	now := time.Now()
   930  	defer func() {
   931  		t.lastPingAt = now
   932  	}()
   933  	// A reset ping strikes means that we don't need to check for policy
   934  	// violation for this ping and the pingStrikes counter should be set
   935  	// to 0.
   936  	if atomic.CompareAndSwapUint32(&t.resetPingStrikes, 1, 0) {
   937  		t.pingStrikes = 0
   938  		return
   939  	}
   940  	t.mu.Lock()
   941  	ns := len(t.activeStreams)
   942  	t.mu.Unlock()
   943  	if ns < 1 && !t.kep.PermitWithoutStream {
   944  		// Keepalive shouldn't be active thus, this new ping should
   945  		// have come after at least defaultPingTimeout.
   946  		if t.lastPingAt.Add(defaultPingTimeout).After(now) {
   947  			t.pingStrikes++
   948  		}
   949  	} else {
   950  		// Check if keepalive policy is respected.
   951  		if t.lastPingAt.Add(t.kep.MinTime).After(now) {
   952  			t.pingStrikes++
   953  		}
   954  	}
   955  
   956  	if t.pingStrikes > maxPingStrikes {
   957  		// Send goaway and close the connection.
   958  		t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings"), closeConn: errors.New("got too many pings from the client")})
   959  	}
   960  }
   961  
   962  func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) {
   963  	t.controlBuf.put(&incomingWindowUpdate{
   964  		streamID:  f.Header().StreamID,
   965  		increment: f.Increment,
   966  	})
   967  }
   968  
   969  func appendHeaderFieldsFromMD(headerFields []hpack.HeaderField, md metadata.MD) []hpack.HeaderField {
   970  	for k, vv := range md {
   971  		if isReservedHeader(k) {
   972  			// Clients don't tolerate reading restricted headers after some non restricted ones were sent.
   973  			continue
   974  		}
   975  		for _, v := range vv {
   976  			headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
   977  		}
   978  	}
   979  	return headerFields
   980  }
   981  
   982  func (t *http2Server) checkForHeaderListSize(it any) bool {
   983  	if t.maxSendHeaderListSize == nil {
   984  		return true
   985  	}
   986  	hdrFrame := it.(*headerFrame)
   987  	var sz int64
   988  	for _, f := range hdrFrame.hf {
   989  		if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
   990  			if t.logger.V(logLevel) {
   991  				t.logger.Infof("Header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
   992  			}
   993  			return false
   994  		}
   995  	}
   996  	return true
   997  }
   998  
   999  func (t *http2Server) streamContextErr(s *ServerStream) error {
  1000  	select {
  1001  	case <-t.done:
  1002  		return ErrConnClosing
  1003  	default:
  1004  	}
  1005  	return ContextErr(s.ctx.Err())
  1006  }
  1007  
  1008  // WriteHeader sends the header metadata md back to the client.
  1009  func (t *http2Server) writeHeader(s *ServerStream, md metadata.MD) error {
  1010  	s.hdrMu.Lock()
  1011  	defer s.hdrMu.Unlock()
  1012  	if s.getState() == streamDone {
  1013  		return t.streamContextErr(s)
  1014  	}
  1015  
  1016  	if s.updateHeaderSent() {
  1017  		return ErrIllegalHeaderWrite
  1018  	}
  1019  
  1020  	if md.Len() > 0 {
  1021  		if s.header.Len() > 0 {
  1022  			s.header = metadata.Join(s.header, md)
  1023  		} else {
  1024  			s.header = md
  1025  		}
  1026  	}
  1027  	if err := t.writeHeaderLocked(s); err != nil {
  1028  		switch e := err.(type) {
  1029  		case ConnectionError:
  1030  			return status.Error(codes.Unavailable, e.Desc)
  1031  		default:
  1032  			return status.Convert(err).Err()
  1033  		}
  1034  	}
  1035  	return nil
  1036  }
  1037  
  1038  func (t *http2Server) writeHeaderLocked(s *ServerStream) error {
  1039  	// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
  1040  	// first and create a slice of that exact size.
  1041  	headerFields := make([]hpack.HeaderField, 0, 2) // at least :status, content-type will be there if none else.
  1042  	headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"})
  1043  	headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: grpcutil.ContentType(s.contentSubtype)})
  1044  	if s.sendCompress != "" {
  1045  		headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
  1046  	}
  1047  	headerFields = appendHeaderFieldsFromMD(headerFields, s.header)
  1048  	hf := &headerFrame{
  1049  		streamID:  s.id,
  1050  		hf:        headerFields,
  1051  		endStream: false,
  1052  		onWrite:   t.setResetPingStrikes,
  1053  	}
  1054  	success, err := t.controlBuf.executeAndPut(func() bool { return t.checkForHeaderListSize(hf) }, hf)
  1055  	if !success {
  1056  		if err != nil {
  1057  			return err
  1058  		}
  1059  		t.closeStream(s, true, http2.ErrCodeInternal, false)
  1060  		return ErrHeaderListSizeLimitViolation
  1061  	}
  1062  	for _, sh := range t.stats {
  1063  		// Note: Headers are compressed with hpack after this call returns.
  1064  		// No WireLength field is set here.
  1065  		outHeader := &stats.OutHeader{
  1066  			Header:      s.header.Copy(),
  1067  			Compression: s.sendCompress,
  1068  		}
  1069  		sh.HandleRPC(s.Context(), outHeader)
  1070  	}
  1071  	return nil
  1072  }
  1073  
  1074  // writeStatus sends stream status to the client and terminates the stream.
  1075  // There is no further I/O operations being able to perform on this stream.
  1076  // TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early
  1077  // OK is adopted.
  1078  func (t *http2Server) writeStatus(s *ServerStream, st *status.Status) error {
  1079  	s.hdrMu.Lock()
  1080  	defer s.hdrMu.Unlock()
  1081  
  1082  	if s.getState() == streamDone {
  1083  		return nil
  1084  	}
  1085  
  1086  	// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
  1087  	// first and create a slice of that exact size.
  1088  	headerFields := make([]hpack.HeaderField, 0, 2) // grpc-status and grpc-message will be there if none else.
  1089  	if !s.updateHeaderSent() {                      // No headers have been sent.
  1090  		if len(s.header) > 0 { // Send a separate header frame.
  1091  			if err := t.writeHeaderLocked(s); err != nil {
  1092  				return err
  1093  			}
  1094  		} else { // Send a trailer only response.
  1095  			headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"})
  1096  			headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: grpcutil.ContentType(s.contentSubtype)})
  1097  		}
  1098  	}
  1099  	headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status", Value: strconv.Itoa(int(st.Code()))})
  1100  	headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())})
  1101  
  1102  	if p := istatus.RawStatusProto(st); len(p.GetDetails()) > 0 {
  1103  		// Do not use the user's grpc-status-details-bin (if present) if we are
  1104  		// even attempting to set our own.
  1105  		delete(s.trailer, grpcStatusDetailsBinHeader)
  1106  		stBytes, err := proto.Marshal(p)
  1107  		if err != nil {
  1108  			// TODO: return error instead, when callers are able to handle it.
  1109  			t.logger.Errorf("Failed to marshal rpc status: %s, error: %v", pretty.ToJSON(p), err)
  1110  		} else {
  1111  			headerFields = append(headerFields, hpack.HeaderField{Name: grpcStatusDetailsBinHeader, Value: encodeBinHeader(stBytes)})
  1112  		}
  1113  	}
  1114  
  1115  	// Attach the trailer metadata.
  1116  	headerFields = appendHeaderFieldsFromMD(headerFields, s.trailer)
  1117  	trailingHeader := &headerFrame{
  1118  		streamID:  s.id,
  1119  		hf:        headerFields,
  1120  		endStream: true,
  1121  		onWrite:   t.setResetPingStrikes,
  1122  	}
  1123  
  1124  	success, err := t.controlBuf.executeAndPut(func() bool {
  1125  		return t.checkForHeaderListSize(trailingHeader)
  1126  	}, nil)
  1127  	if !success {
  1128  		if err != nil {
  1129  			return err
  1130  		}
  1131  		t.closeStream(s, true, http2.ErrCodeInternal, false)
  1132  		return ErrHeaderListSizeLimitViolation
  1133  	}
  1134  	// Send a RST_STREAM after the trailers if the client has not already half-closed.
  1135  	rst := s.getState() == streamActive
  1136  	t.finishStream(s, rst, http2.ErrCodeNo, trailingHeader, true)
  1137  	for _, sh := range t.stats {
  1138  		// Note: The trailer fields are compressed with hpack after this call returns.
  1139  		// No WireLength field is set here.
  1140  		sh.HandleRPC(s.Context(), &stats.OutTrailer{
  1141  			Trailer: s.trailer.Copy(),
  1142  		})
  1143  	}
  1144  	return nil
  1145  }
  1146  
  1147  // Write converts the data into HTTP2 data frame and sends it out. Non-nil error
  1148  // is returns if it fails (e.g., framing error, transport error).
  1149  func (t *http2Server) write(s *ServerStream, hdr []byte, data mem.BufferSlice, _ *WriteOptions) error {
  1150  	if !s.isHeaderSent() { // Headers haven't been written yet.
  1151  		if err := t.writeHeader(s, nil); err != nil {
  1152  			return err
  1153  		}
  1154  	} else {
  1155  		// Writing headers checks for this condition.
  1156  		if s.getState() == streamDone {
  1157  			return t.streamContextErr(s)
  1158  		}
  1159  	}
  1160  
  1161  	df := &dataFrame{
  1162  		streamID:    s.id,
  1163  		h:           hdr,
  1164  		data:        data,
  1165  		onEachWrite: t.setResetPingStrikes,
  1166  	}
  1167  	dataLen := data.Len()
  1168  	if err := s.wq.get(int32(len(hdr) + dataLen)); err != nil {
  1169  		return t.streamContextErr(s)
  1170  	}
  1171  	data.Ref()
  1172  	if err := t.controlBuf.put(df); err != nil {
  1173  		data.Free()
  1174  		return err
  1175  	}
  1176  	t.incrMsgSent()
  1177  	return nil
  1178  }
  1179  
  1180  // keepalive running in a separate goroutine does the following:
  1181  // 1. Gracefully closes an idle connection after a duration of keepalive.MaxConnectionIdle.
  1182  // 2. Gracefully closes any connection after a duration of keepalive.MaxConnectionAge.
  1183  // 3. Forcibly closes a connection after an additive period of keepalive.MaxConnectionAgeGrace over keepalive.MaxConnectionAge.
  1184  // 4. Makes sure a connection is alive by sending pings with a frequency of keepalive.Time and closes a non-responsive connection
  1185  // after an additional duration of keepalive.Timeout.
  1186  func (t *http2Server) keepalive() {
  1187  	p := &ping{}
  1188  	// True iff a ping has been sent, and no data has been received since then.
  1189  	outstandingPing := false
  1190  	// Amount of time remaining before which we should receive an ACK for the
  1191  	// last sent ping.
  1192  	kpTimeoutLeft := time.Duration(0)
  1193  	// Records the last value of t.lastRead before we go block on the timer.
  1194  	// This is required to check for read activity since then.
  1195  	prevNano := time.Now().UnixNano()
  1196  	// Initialize the different timers to their default values.
  1197  	idleTimer := time.NewTimer(t.kp.MaxConnectionIdle)
  1198  	ageTimer := time.NewTimer(t.kp.MaxConnectionAge)
  1199  	kpTimer := time.NewTimer(t.kp.Time)
  1200  	defer func() {
  1201  		// We need to drain the underlying channel in these timers after a call
  1202  		// to Stop(), only if we are interested in resetting them. Clearly we
  1203  		// are not interested in resetting them here.
  1204  		idleTimer.Stop()
  1205  		ageTimer.Stop()
  1206  		kpTimer.Stop()
  1207  	}()
  1208  
  1209  	for {
  1210  		select {
  1211  		case <-idleTimer.C:
  1212  			t.mu.Lock()
  1213  			idle := t.idle
  1214  			if idle.IsZero() { // The connection is non-idle.
  1215  				t.mu.Unlock()
  1216  				idleTimer.Reset(t.kp.MaxConnectionIdle)
  1217  				continue
  1218  			}
  1219  			val := t.kp.MaxConnectionIdle - time.Since(idle)
  1220  			t.mu.Unlock()
  1221  			if val <= 0 {
  1222  				// The connection has been idle for a duration of keepalive.MaxConnectionIdle or more.
  1223  				// Gracefully close the connection.
  1224  				t.Drain("max_idle")
  1225  				return
  1226  			}
  1227  			idleTimer.Reset(val)
  1228  		case <-ageTimer.C:
  1229  			t.Drain("max_age")
  1230  			ageTimer.Reset(t.kp.MaxConnectionAgeGrace)
  1231  			select {
  1232  			case <-ageTimer.C:
  1233  				// Close the connection after grace period.
  1234  				if t.logger.V(logLevel) {
  1235  					t.logger.Infof("Closing server transport due to maximum connection age")
  1236  				}
  1237  				t.controlBuf.put(closeConnection{})
  1238  			case <-t.done:
  1239  			}
  1240  			return
  1241  		case <-kpTimer.C:
  1242  			lastRead := atomic.LoadInt64(&t.lastRead)
  1243  			if lastRead > prevNano {
  1244  				// There has been read activity since the last time we were
  1245  				// here. Setup the timer to fire at kp.Time seconds from
  1246  				// lastRead time and continue.
  1247  				outstandingPing = false
  1248  				kpTimer.Reset(time.Duration(lastRead) + t.kp.Time - time.Duration(time.Now().UnixNano()))
  1249  				prevNano = lastRead
  1250  				continue
  1251  			}
  1252  			if outstandingPing && kpTimeoutLeft <= 0 {
  1253  				t.Close(fmt.Errorf("keepalive ping not acked within timeout %s", t.kp.Timeout))
  1254  				return
  1255  			}
  1256  			if !outstandingPing {
  1257  				if channelz.IsOn() {
  1258  					t.channelz.SocketMetrics.KeepAlivesSent.Add(1)
  1259  				}
  1260  				t.controlBuf.put(p)
  1261  				kpTimeoutLeft = t.kp.Timeout
  1262  				outstandingPing = true
  1263  			}
  1264  			// The amount of time to sleep here is the minimum of kp.Time and
  1265  			// timeoutLeft. This will ensure that we wait only for kp.Time
  1266  			// before sending out the next ping (for cases where the ping is
  1267  			// acked).
  1268  			sleepDuration := min(t.kp.Time, kpTimeoutLeft)
  1269  			kpTimeoutLeft -= sleepDuration
  1270  			kpTimer.Reset(sleepDuration)
  1271  		case <-t.done:
  1272  			return
  1273  		}
  1274  	}
  1275  }
  1276  
  1277  // Close starts shutting down the http2Server transport.
  1278  // TODO(zhaoq): Now the destruction is not blocked on any pending streams. This
  1279  // could cause some resource issue. Revisit this later.
  1280  func (t *http2Server) Close(err error) {
  1281  	t.mu.Lock()
  1282  	if t.state == closing {
  1283  		t.mu.Unlock()
  1284  		return
  1285  	}
  1286  	if t.logger.V(logLevel) {
  1287  		t.logger.Infof("Closing: %v", err)
  1288  	}
  1289  	t.state = closing
  1290  	streams := t.activeStreams
  1291  	t.activeStreams = nil
  1292  	t.mu.Unlock()
  1293  	t.controlBuf.finish()
  1294  	close(t.done)
  1295  	if err := t.conn.Close(); err != nil && t.logger.V(logLevel) {
  1296  		t.logger.Infof("Error closing underlying net.Conn during Close: %v", err)
  1297  	}
  1298  	channelz.RemoveEntry(t.channelz.ID)
  1299  	// Cancel all active streams.
  1300  	for _, s := range streams {
  1301  		s.cancel()
  1302  	}
  1303  }
  1304  
  1305  // deleteStream deletes the stream s from transport's active streams.
  1306  func (t *http2Server) deleteStream(s *ServerStream, eosReceived bool) {
  1307  	t.mu.Lock()
  1308  	if _, ok := t.activeStreams[s.id]; ok {
  1309  		delete(t.activeStreams, s.id)
  1310  		if len(t.activeStreams) == 0 {
  1311  			t.idle = time.Now()
  1312  		}
  1313  	}
  1314  	t.mu.Unlock()
  1315  
  1316  	if channelz.IsOn() {
  1317  		if eosReceived {
  1318  			t.channelz.SocketMetrics.StreamsSucceeded.Add(1)
  1319  		} else {
  1320  			t.channelz.SocketMetrics.StreamsFailed.Add(1)
  1321  		}
  1322  	}
  1323  }
  1324  
  1325  // finishStream closes the stream and puts the trailing headerFrame into controlbuf.
  1326  func (t *http2Server) finishStream(s *ServerStream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) {
  1327  	// In case stream sending and receiving are invoked in separate
  1328  	// goroutines (e.g., bi-directional streaming), cancel needs to be
  1329  	// called to interrupt the potential blocking on other goroutines.
  1330  	s.cancel()
  1331  
  1332  	oldState := s.swapState(streamDone)
  1333  	if oldState == streamDone {
  1334  		// If the stream was already done, return.
  1335  		return
  1336  	}
  1337  
  1338  	hdr.cleanup = &cleanupStream{
  1339  		streamID: s.id,
  1340  		rst:      rst,
  1341  		rstCode:  rstCode,
  1342  		onWrite: func() {
  1343  			t.deleteStream(s, eosReceived)
  1344  		},
  1345  	}
  1346  	t.controlBuf.put(hdr)
  1347  }
  1348  
  1349  // closeStream clears the footprint of a stream when the stream is not needed any more.
  1350  func (t *http2Server) closeStream(s *ServerStream, rst bool, rstCode http2.ErrCode, eosReceived bool) {
  1351  	// In case stream sending and receiving are invoked in separate
  1352  	// goroutines (e.g., bi-directional streaming), cancel needs to be
  1353  	// called to interrupt the potential blocking on other goroutines.
  1354  	s.cancel()
  1355  
  1356  	oldState := s.swapState(streamDone)
  1357  	if oldState == streamDone {
  1358  		return
  1359  	}
  1360  	t.deleteStream(s, eosReceived)
  1361  
  1362  	t.controlBuf.put(&cleanupStream{
  1363  		streamID: s.id,
  1364  		rst:      rst,
  1365  		rstCode:  rstCode,
  1366  		onWrite:  func() {},
  1367  	})
  1368  }
  1369  
  1370  func (t *http2Server) Drain(debugData string) {
  1371  	t.mu.Lock()
  1372  	defer t.mu.Unlock()
  1373  	if t.drainEvent != nil {
  1374  		return
  1375  	}
  1376  	t.drainEvent = grpcsync.NewEvent()
  1377  	t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte(debugData), headsUp: true})
  1378  }
  1379  
  1380  var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}}
  1381  
  1382  // Handles outgoing GoAway and returns true if loopy needs to put itself
  1383  // in draining mode.
  1384  func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
  1385  	t.maxStreamMu.Lock()
  1386  	t.mu.Lock()
  1387  	if t.state == closing { // TODO(mmukhi): This seems unnecessary.
  1388  		t.mu.Unlock()
  1389  		t.maxStreamMu.Unlock()
  1390  		// The transport is closing.
  1391  		return false, ErrConnClosing
  1392  	}
  1393  	if !g.headsUp {
  1394  		// Stop accepting more streams now.
  1395  		t.state = draining
  1396  		sid := t.maxStreamID
  1397  		retErr := g.closeConn
  1398  		if len(t.activeStreams) == 0 {
  1399  			retErr = errors.New("second GOAWAY written and no active streams left to process")
  1400  		}
  1401  		t.mu.Unlock()
  1402  		t.maxStreamMu.Unlock()
  1403  		if err := t.framer.fr.WriteGoAway(sid, g.code, g.debugData); err != nil {
  1404  			return false, err
  1405  		}
  1406  		t.framer.writer.Flush()
  1407  		if retErr != nil {
  1408  			return false, retErr
  1409  		}
  1410  		return true, nil
  1411  	}
  1412  	t.mu.Unlock()
  1413  	t.maxStreamMu.Unlock()
  1414  	// For a graceful close, send out a GoAway with stream ID of MaxUInt32,
  1415  	// Follow that with a ping and wait for the ack to come back or a timer
  1416  	// to expire. During this time accept new streams since they might have
  1417  	// originated before the GoAway reaches the client.
  1418  	// After getting the ack or timer expiration send out another GoAway this
  1419  	// time with an ID of the max stream server intends to process.
  1420  	if err := t.framer.fr.WriteGoAway(math.MaxUint32, http2.ErrCodeNo, g.debugData); err != nil {
  1421  		return false, err
  1422  	}
  1423  	if err := t.framer.fr.WritePing(false, goAwayPing.data); err != nil {
  1424  		return false, err
  1425  	}
  1426  	go func() {
  1427  		timer := time.NewTimer(5 * time.Second)
  1428  		defer timer.Stop()
  1429  		select {
  1430  		case <-t.drainEvent.Done():
  1431  		case <-timer.C:
  1432  		case <-t.done:
  1433  			return
  1434  		}
  1435  		t.controlBuf.put(&goAway{code: g.code, debugData: g.debugData})
  1436  	}()
  1437  	return false, nil
  1438  }
  1439  
  1440  func (t *http2Server) socketMetrics() *channelz.EphemeralSocketMetrics {
  1441  	return &channelz.EphemeralSocketMetrics{
  1442  		LocalFlowControlWindow:  int64(t.fc.getSize()),
  1443  		RemoteFlowControlWindow: t.getOutFlowWindow(),
  1444  	}
  1445  }
  1446  
  1447  func (t *http2Server) incrMsgSent() {
  1448  	if channelz.IsOn() {
  1449  		t.channelz.SocketMetrics.MessagesSent.Add(1)
  1450  		t.channelz.SocketMetrics.LastMessageSentTimestamp.Add(1)
  1451  	}
  1452  }
  1453  
  1454  func (t *http2Server) incrMsgRecv() {
  1455  	if channelz.IsOn() {
  1456  		t.channelz.SocketMetrics.MessagesReceived.Add(1)
  1457  		t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Add(1)
  1458  	}
  1459  }
  1460  
  1461  func (t *http2Server) getOutFlowWindow() int64 {
  1462  	resp := make(chan uint32, 1)
  1463  	timer := time.NewTimer(time.Second)
  1464  	defer timer.Stop()
  1465  	t.controlBuf.put(&outFlowControlSizeRequest{resp})
  1466  	select {
  1467  	case sz := <-resp:
  1468  		return int64(sz)
  1469  	case <-t.done:
  1470  		return -1
  1471  	case <-timer.C:
  1472  		return -2
  1473  	}
  1474  }
  1475  
  1476  // Peer returns the peer of the transport.
  1477  func (t *http2Server) Peer() *peer.Peer {
  1478  	return &peer.Peer{
  1479  		Addr:      t.peer.Addr,
  1480  		LocalAddr: t.peer.LocalAddr,
  1481  		AuthInfo:  t.peer.AuthInfo, // Can be nil
  1482  	}
  1483  }
  1484  
  1485  func getJitter(v time.Duration) time.Duration {
  1486  	if v == infinity {
  1487  		return 0
  1488  	}
  1489  	// Generate a jitter between +/- 10% of the value.
  1490  	r := int64(v / 10)
  1491  	j := rand.Int64N(2*r) - r
  1492  	return time.Duration(j)
  1493  }
  1494  
  1495  type connectionKey struct{}
  1496  
  1497  // GetConnection gets the connection from the context.
  1498  func GetConnection(ctx context.Context) net.Conn {
  1499  	conn, _ := ctx.Value(connectionKey{}).(net.Conn)
  1500  	return conn
  1501  }
  1502  
  1503  // SetConnection adds the connection to the context to be able to get
  1504  // information about the destination ip and port for an incoming RPC. This also
  1505  // allows any unary or streaming interceptors to see the connection.
  1506  func SetConnection(ctx context.Context, conn net.Conn) context.Context {
  1507  	return context.WithValue(ctx, connectionKey{}, conn)
  1508  }