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