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