github.com/cloudwego/kitex@v0.9.0/pkg/remote/trans/nphttp2/grpc/transport.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   * This file may have been modified by CloudWeGo authors. All CloudWeGo
    18   * Modifications are Copyright 2021 CloudWeGo Authors.
    19   */
    20  
    21  // Package grpc defines and implements message oriented communication
    22  // channel to complete various transactions (e.g., an RPC).  It is meant for
    23  // grpc-internal usage and is not intended to be imported directly by users.
    24  package grpc
    25  
    26  import (
    27  	"bytes"
    28  	"context"
    29  	"crypto/tls"
    30  	"errors"
    31  	"fmt"
    32  	"io"
    33  	"net"
    34  	"sync"
    35  	"sync/atomic"
    36  
    37  	"github.com/cloudwego/kitex/pkg/kerrors"
    38  	"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/codes"
    39  	"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/metadata"
    40  	"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/status"
    41  )
    42  
    43  type bufferPool struct {
    44  	pool sync.Pool
    45  }
    46  
    47  func newBufferPool() *bufferPool {
    48  	return &bufferPool{
    49  		pool: sync.Pool{
    50  			New: func() interface{} {
    51  				return new(bytes.Buffer)
    52  			},
    53  		},
    54  	}
    55  }
    56  
    57  func (p *bufferPool) get() *bytes.Buffer {
    58  	return p.pool.Get().(*bytes.Buffer)
    59  }
    60  
    61  func (p *bufferPool) put(b *bytes.Buffer) {
    62  	p.pool.Put(b)
    63  }
    64  
    65  // recvMsg represents the received msg from the transport. All transport
    66  // protocol specific info has been removed.
    67  type recvMsg struct {
    68  	buffer *bytes.Buffer
    69  	// nil: received some data
    70  	// io.EOF: stream is completed. data is nil.
    71  	// other non-nil error: transport failure. data is nil.
    72  	err error
    73  }
    74  
    75  // recvBuffer is an unbounded channel of recvMsg structs.
    76  //
    77  // Note: recvBuffer differs from buffer.Unbounded only in the fact that it
    78  // holds a channel of recvMsg structs instead of objects implementing "item"
    79  // interface. recvBuffer is written to much more often and using strict recvMsg
    80  // structs helps avoid allocation in "recvBuffer.put"
    81  type recvBuffer struct {
    82  	c       chan recvMsg
    83  	mu      sync.Mutex
    84  	backlog []recvMsg
    85  	err     error
    86  }
    87  
    88  func newRecvBuffer() *recvBuffer {
    89  	b := &recvBuffer{
    90  		c: make(chan recvMsg, 1),
    91  	}
    92  	return b
    93  }
    94  
    95  func (b *recvBuffer) put(r recvMsg) {
    96  	b.mu.Lock()
    97  	if b.err != nil {
    98  		b.mu.Unlock()
    99  		// An error had occurred earlier, don't accept more
   100  		// data or errors.
   101  		return
   102  	}
   103  	b.err = r.err
   104  	if len(b.backlog) == 0 {
   105  		select {
   106  		case b.c <- r:
   107  			b.mu.Unlock()
   108  			return
   109  		default:
   110  		}
   111  	}
   112  	b.backlog = append(b.backlog, r)
   113  	b.mu.Unlock()
   114  }
   115  
   116  func (b *recvBuffer) load() {
   117  	b.mu.Lock()
   118  	if len(b.backlog) > 0 {
   119  		select {
   120  		case b.c <- b.backlog[0]:
   121  			b.backlog[0] = recvMsg{}
   122  			b.backlog = b.backlog[1:]
   123  		default:
   124  		}
   125  	}
   126  	b.mu.Unlock()
   127  }
   128  
   129  // get returns the channel that receives a recvMsg in the buffer.
   130  //
   131  // Upon receipt of a recvMsg, the caller should call load to send another
   132  // recvMsg onto the channel if there is any.
   133  func (b *recvBuffer) get() <-chan recvMsg {
   134  	return b.c
   135  }
   136  
   137  // recvBufferReader implements io.Reader interface to read the data from
   138  // recvBuffer.
   139  type recvBufferReader struct {
   140  	closeStream func(error) // Closes the client transport stream with the given error and nil trailer metadata.
   141  	ctx         context.Context
   142  	ctxDone     <-chan struct{} // cache of ctx.Done() (for performance).
   143  	recv        *recvBuffer
   144  	last        *bytes.Buffer // Stores the remaining data in the previous calls.
   145  	err         error
   146  	freeBuffer  func(*bytes.Buffer)
   147  }
   148  
   149  // Read reads the next len(p) bytes from last. If last is drained, it tries to
   150  // read additional data from recv. It blocks if there no additional data available
   151  // in recv. If Read returns any non-nil error, it will continue to return that error.
   152  func (r *recvBufferReader) Read(p []byte) (n int, err error) {
   153  	if r.err != nil {
   154  		return 0, r.err
   155  	}
   156  	if r.last != nil {
   157  		// Read remaining data left in last call.
   158  		copied, _ := r.last.Read(p)
   159  		if r.last.Len() == 0 {
   160  			r.freeBuffer(r.last)
   161  			r.last = nil
   162  		}
   163  		return copied, nil
   164  	}
   165  	if r.closeStream != nil {
   166  		n, r.err = r.readClient(p)
   167  	} else {
   168  		n, r.err = r.read(p)
   169  	}
   170  	return n, r.err
   171  }
   172  
   173  func (r *recvBufferReader) read(p []byte) (n int, err error) {
   174  	select {
   175  	case <-r.ctxDone:
   176  		return 0, ContextErr(r.ctx.Err())
   177  	case m := <-r.recv.get():
   178  		return r.readAdditional(m, p)
   179  	}
   180  }
   181  
   182  func (r *recvBufferReader) readClient(p []byte) (n int, err error) {
   183  	// If the context is canceled, then closes the stream with nil metadata.
   184  	// closeStream writes its error parameter to r.recv as a recvMsg.
   185  	// r.readAdditional acts on that message and returns the necessary error.
   186  	select {
   187  	case <-r.ctxDone:
   188  		// Note that this adds the ctx error to the end of recv buffer, and
   189  		// reads from the head. This will delay the error until recv buffer is
   190  		// empty, thus will delay ctx cancellation in Recv().
   191  		//
   192  		// It's done this way to fix a race between ctx cancel and trailer. The
   193  		// race was, stream.Recv() may return ctx error if ctxDone wins the
   194  		// race, but stream.Trailer() may return a non-nil md because the stream
   195  		// was not marked as done when trailer is received. This closeStream
   196  		// call will mark stream as done, thus fix the race.
   197  		//
   198  		// TODO: delaying ctx error seems like a unnecessary side effect. What
   199  		// we really want is to mark the stream as done, and return ctx error
   200  		// faster.
   201  		r.closeStream(ContextErr(r.ctx.Err()))
   202  		m := <-r.recv.get()
   203  		return r.readAdditional(m, p)
   204  	case m := <-r.recv.get():
   205  		return r.readAdditional(m, p)
   206  	}
   207  }
   208  
   209  func (r *recvBufferReader) readAdditional(m recvMsg, p []byte) (n int, err error) {
   210  	r.recv.load()
   211  	if m.err != nil {
   212  		return 0, m.err
   213  	}
   214  	copied, _ := m.buffer.Read(p)
   215  	if m.buffer.Len() == 0 {
   216  		r.freeBuffer(m.buffer)
   217  		r.last = nil
   218  	} else {
   219  		r.last = m.buffer
   220  	}
   221  	return copied, nil
   222  }
   223  
   224  type streamState uint32
   225  
   226  const (
   227  	streamActive    streamState = iota
   228  	streamWriteDone             // EndStream sent
   229  	streamReadDone              // EndStream received
   230  	streamDone                  // the entire stream is finished.
   231  )
   232  
   233  // Stream represents an RPC in the transport layer.
   234  type Stream struct {
   235  	id           uint32
   236  	st           ServerTransport    // nil for client side Stream
   237  	ct           *http2Client       // nil for server side Stream
   238  	ctx          context.Context    // the associated context of the stream
   239  	cancel       context.CancelFunc // always nil for client side Stream
   240  	done         chan struct{}      // closed at the end of stream to unblock writers. On the client side.
   241  	ctxDone      <-chan struct{}    // same as done chan but for server side. Cache of ctx.Done() (for performance)
   242  	method       string             // the associated RPC method of the stream
   243  	recvCompress string
   244  	sendCompress string
   245  	buf          *recvBuffer
   246  	trReader     io.Reader
   247  	fc           *inFlow
   248  	wq           *writeQuota
   249  
   250  	// Callback to state application's intentions to read data. This
   251  	// is used to adjust flow control, if needed.
   252  	requestRead func(int)
   253  
   254  	headerChan       chan struct{} // closed to indicate the end of header metadata.
   255  	headerChanClosed uint32        // set when headerChan is closed. Used to avoid closing headerChan multiple times.
   256  	// headerValid indicates whether a valid header was received.  Only
   257  	// meaningful after headerChan is closed (always call waitOnHeader() before
   258  	// reading its value).  Not valid on server side.
   259  	headerValid bool
   260  
   261  	// hdrMu protects header and trailer metadata on the server-side.
   262  	hdrMu sync.Mutex
   263  	// On client side, header keeps the received header metadata.
   264  	//
   265  	// On server side, header keeps the header set by SetHeader(). The complete
   266  	// header will merged into this after t.WriteHeader() is called.
   267  	header  metadata.MD
   268  	trailer metadata.MD // the key-value map of trailer metadata.
   269  
   270  	noHeaders bool // set if the client never received headers (set only after the stream is done).
   271  
   272  	// On the server-side, headerSent is atomically set to 1 when the headers are sent out.
   273  	headerSent uint32
   274  
   275  	state streamState
   276  
   277  	// On client-side it is the status error received from the server.
   278  	// On server-side it is unused.
   279  	status       *status.Status
   280  	bizStatusErr kerrors.BizStatusErrorIface
   281  
   282  	bytesReceived uint32 // indicates whether any bytes have been received on this stream
   283  	unprocessed   uint32 // set if the server sends a refused stream or GOAWAY including this stream
   284  
   285  	// contentSubtype is the content-subtype for requests.
   286  	// this must be lowercase or the behavior is undefined.
   287  	contentSubtype string
   288  }
   289  
   290  // isHeaderSent is only valid on the server-side.
   291  func (s *Stream) isHeaderSent() bool {
   292  	return atomic.LoadUint32(&s.headerSent) == 1
   293  }
   294  
   295  // updateHeaderSent updates headerSent and returns true
   296  // if it was already set. It is valid only on server-side.
   297  func (s *Stream) updateHeaderSent() bool {
   298  	return atomic.SwapUint32(&s.headerSent, 1) == 1
   299  }
   300  
   301  func (s *Stream) swapState(st streamState) streamState {
   302  	return streamState(atomic.SwapUint32((*uint32)(&s.state), uint32(st)))
   303  }
   304  
   305  func (s *Stream) compareAndSwapState(oldState, newState streamState) bool {
   306  	return atomic.CompareAndSwapUint32((*uint32)(&s.state), uint32(oldState), uint32(newState))
   307  }
   308  
   309  func (s *Stream) getState() streamState {
   310  	return streamState(atomic.LoadUint32((*uint32)(&s.state)))
   311  }
   312  
   313  func (s *Stream) waitOnHeader() {
   314  	if s.headerChan == nil {
   315  		// On the server headerChan is always nil since a stream originates
   316  		// only after having received headers.
   317  		return
   318  	}
   319  	select {
   320  	case <-s.ctx.Done():
   321  		// Close the stream to prevent headers/trailers from changing after
   322  		// this function returns.
   323  		s.ct.CloseStream(s, ContextErr(s.ctx.Err()))
   324  		// headerChan could possibly not be closed yet if closeStream raced
   325  		// with operateHeaders; wait until it is closed explicitly here.
   326  		<-s.headerChan
   327  	case <-s.headerChan:
   328  	}
   329  }
   330  
   331  // RecvCompress returns the compression algorithm applied to the inbound
   332  // message. It is empty string if there is no compression applied.
   333  func (s *Stream) RecvCompress() string {
   334  	s.waitOnHeader()
   335  	return s.recvCompress
   336  }
   337  
   338  // SendCompress returns the compression algorithm applied to the outbound
   339  // message. It is empty string if there is no compression applied.
   340  func (s *Stream) SendCompress() string {
   341  	s.waitOnHeader()
   342  	return s.sendCompress
   343  }
   344  
   345  // SetSendCompress sets the compression algorithm to the stream.
   346  func (s *Stream) SetSendCompress(str string) {
   347  	s.sendCompress = str
   348  }
   349  
   350  // Done returns a channel which is closed when it receives the final status
   351  // from the server.
   352  func (s *Stream) Done() <-chan struct{} {
   353  	return s.done
   354  }
   355  
   356  // Header returns the header metadata of the stream.
   357  //
   358  // On client side, it acquires the key-value pairs of header metadata once it is
   359  // available. It blocks until i) the metadata is ready or ii) there is no header
   360  // metadata or iii) the stream is canceled/expired.
   361  //
   362  // On server side, it returns the out header after t.WriteHeader is called.  It
   363  // does not block and must not be called until after WriteHeader.
   364  func (s *Stream) Header() (metadata.MD, error) {
   365  	if s.headerChan == nil {
   366  		// On server side, return the header in stream. It will be the out
   367  		// header after t.WriteHeader is called.
   368  		return s.header.Copy(), nil
   369  	}
   370  	s.waitOnHeader()
   371  	if !s.headerValid {
   372  		return nil, s.status.Err()
   373  	}
   374  	return s.header.Copy(), nil
   375  }
   376  
   377  // TrailersOnly blocks until a header or trailers-only frame is received and
   378  // then returns true if the stream was trailers-only.  If the stream ends
   379  // before headers are received, returns true, nil.  Client-side only.
   380  func (s *Stream) TrailersOnly() bool {
   381  	s.waitOnHeader()
   382  	return s.noHeaders
   383  }
   384  
   385  // Trailer returns the cached trailer metedata. Note that if it is not called
   386  // after the entire stream is done, it could return an empty MD. Client
   387  // side only.
   388  // It can be safely read only after stream has ended that is either read
   389  // or write have returned io.EOF.
   390  func (s *Stream) Trailer() metadata.MD {
   391  	c := s.trailer.Copy()
   392  	return c
   393  }
   394  
   395  // ContentSubtype returns the content-subtype for a request. For example, a
   396  // content-subtype of "proto" will result in a content-type of
   397  // "application/grpc+proto". This will always be lowercase.  See
   398  // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
   399  // more details.
   400  func (s *Stream) ContentSubtype() string {
   401  	return s.contentSubtype
   402  }
   403  
   404  // Context returns the context of the stream.
   405  func (s *Stream) Context() context.Context {
   406  	return s.ctx
   407  }
   408  
   409  // Method returns the method for the stream.
   410  func (s *Stream) Method() string {
   411  	return s.method
   412  }
   413  
   414  // Status returns the status received from the server.
   415  // Status can be read safely only after the stream has ended,
   416  // that is, after Done() is closed.
   417  func (s *Stream) Status() *status.Status {
   418  	return s.status
   419  }
   420  
   421  func (s *Stream) SetBizStatusErr(bizStatusErr kerrors.BizStatusErrorIface) {
   422  	s.bizStatusErr = bizStatusErr
   423  }
   424  
   425  func (s *Stream) BizStatusErr() kerrors.BizStatusErrorIface {
   426  	return s.bizStatusErr
   427  }
   428  
   429  // SetHeader sets the header metadata. This can be called multiple times.
   430  // Server side only.
   431  // This should not be called in parallel to other data writes.
   432  func (s *Stream) SetHeader(md metadata.MD) error {
   433  	if md.Len() == 0 {
   434  		return nil
   435  	}
   436  	if s.isHeaderSent() || s.getState() == streamDone {
   437  		return ErrIllegalHeaderWrite
   438  	}
   439  	s.hdrMu.Lock()
   440  	s.header = metadata.AppendMD(s.header, md)
   441  	s.hdrMu.Unlock()
   442  	return nil
   443  }
   444  
   445  // SendHeader sends the given header metadata. The given metadata is
   446  // combined with any metadata set by previous calls to SetHeader and
   447  // then written to the transport stream.
   448  func (s *Stream) SendHeader(md metadata.MD) error {
   449  	return s.st.WriteHeader(s, md)
   450  }
   451  
   452  // SetTrailer sets the trailer metadata which will be sent with the RPC status
   453  // by the server. This can be called multiple times. Server side only.
   454  // This should not be called parallel to other data writes.
   455  func (s *Stream) SetTrailer(md metadata.MD) error {
   456  	if md.Len() == 0 {
   457  		return nil
   458  	}
   459  	if s.getState() == streamDone {
   460  		return ErrIllegalHeaderWrite
   461  	}
   462  	s.hdrMu.Lock()
   463  	s.trailer = metadata.AppendMD(s.trailer, md)
   464  	s.hdrMu.Unlock()
   465  	return nil
   466  }
   467  
   468  func (s *Stream) write(m recvMsg) {
   469  	s.buf.put(m)
   470  }
   471  
   472  // Read reads all p bytes from the wire for this stream.
   473  func (s *Stream) Read(p []byte) (n int, err error) {
   474  	// Don't request a read if there was an error earlier
   475  	if er := s.trReader.(*transportReader).er; er != nil {
   476  		return 0, er
   477  	}
   478  	s.requestRead(len(p))
   479  	return io.ReadFull(s.trReader, p)
   480  }
   481  
   482  // StreamWrite only used for unit test
   483  func StreamWrite(s *Stream, buffer *bytes.Buffer) {
   484  	s.write(recvMsg{buffer: buffer})
   485  }
   486  
   487  // CreateStream only used for unit test. Create an independent stream out of http2client / http2server
   488  func CreateStream(id uint32, requestRead func(i int)) *Stream {
   489  	recvBuffer := newRecvBuffer()
   490  	trReader := &transportReader{
   491  		reader: &recvBufferReader{
   492  			recv: recvBuffer,
   493  			freeBuffer: func(buffer *bytes.Buffer) {
   494  				buffer.Reset()
   495  			},
   496  		},
   497  		windowHandler: func(i int) {},
   498  	}
   499  
   500  	stream := &Stream{
   501  		id:          id,
   502  		buf:         recvBuffer,
   503  		trReader:    trReader,
   504  		wq:          newWriteQuota(defaultWriteQuota, nil),
   505  		requestRead: requestRead,
   506  		hdrMu:       sync.Mutex{},
   507  	}
   508  
   509  	return stream
   510  }
   511  
   512  // transportReader reads all the data available for this Stream from the transport and
   513  // passes them into the decoder, which converts them into a gRPC message stream.
   514  // The error is io.EOF when the stream is done or another non-nil error if
   515  // the stream broke.
   516  type transportReader struct {
   517  	reader io.Reader
   518  	// The handler to control the window update procedure for both this
   519  	// particular stream and the associated transport.
   520  	windowHandler func(int)
   521  	er            error
   522  }
   523  
   524  func (t *transportReader) Read(p []byte) (n int, err error) {
   525  	n, err = t.reader.Read(p)
   526  	if err != nil {
   527  		t.er = err
   528  		return
   529  	}
   530  	t.windowHandler(n)
   531  	return
   532  }
   533  
   534  // BytesReceived indicates whether any bytes have been received on this stream.
   535  func (s *Stream) BytesReceived() bool {
   536  	return atomic.LoadUint32(&s.bytesReceived) == 1
   537  }
   538  
   539  // Unprocessed indicates whether the server did not process this stream --
   540  // i.e. it sent a refused stream or GOAWAY including this stream ID.
   541  func (s *Stream) Unprocessed() bool {
   542  	return atomic.LoadUint32(&s.unprocessed) == 1
   543  }
   544  
   545  // state of transport
   546  type transportState int
   547  
   548  const (
   549  	reachable transportState = iota
   550  	closing
   551  	draining
   552  )
   553  
   554  // ServerConfig consists of all the configurations to establish a server transport.
   555  type ServerConfig struct {
   556  	MaxStreams                 uint32
   557  	KeepaliveParams            ServerKeepalive
   558  	KeepaliveEnforcementPolicy EnforcementPolicy
   559  	InitialWindowSize          uint32
   560  	InitialConnWindowSize      uint32
   561  	WriteBufferSize            uint32
   562  	ReadBufferSize             uint32
   563  	MaxHeaderListSize          *uint32
   564  }
   565  
   566  func DefaultServerConfig() *ServerConfig {
   567  	return &ServerConfig{
   568  		WriteBufferSize: defaultWriteBufferSize,
   569  		ReadBufferSize:  defaultReadBufferSize,
   570  	}
   571  }
   572  
   573  // ConnectOptions covers all relevant options for communicating with the server.
   574  type ConnectOptions struct {
   575  	// KeepaliveParams stores the keepalive parameters.
   576  	KeepaliveParams ClientKeepalive
   577  	// InitialWindowSize sets the initial window size for a stream.
   578  	InitialWindowSize uint32
   579  	// InitialConnWindowSize sets the initial window size for a connection.
   580  	InitialConnWindowSize uint32
   581  	// WriteBufferSize sets the size of write buffer which in turn determines how much data can be batched before it's written on the wire.
   582  	WriteBufferSize uint32
   583  	// ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall.
   584  	ReadBufferSize uint32
   585  	// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
   586  	MaxHeaderListSize *uint32
   587  	// ShortConn indicates whether the connection will be reused from grpc conn pool
   588  	ShortConn bool
   589  	// TLSConfig
   590  	TLSConfig *tls.Config
   591  }
   592  
   593  // NewServerTransport creates a ServerTransport with conn or non-nil error
   594  // if it fails.
   595  func NewServerTransport(ctx context.Context, conn net.Conn, cfg *ServerConfig) (ServerTransport, error) {
   596  	return newHTTP2Server(ctx, conn, cfg)
   597  }
   598  
   599  // NewClientTransport establishes the transport with the required ConnectOptions
   600  // and returns it to the caller.
   601  func NewClientTransport(ctx context.Context, conn net.Conn, opts ConnectOptions,
   602  	remoteService string, onGoAway func(GoAwayReason), onClose func(),
   603  ) (ClientTransport, error) {
   604  	return newHTTP2Client(ctx, conn, opts, remoteService, onGoAway, onClose)
   605  }
   606  
   607  // Options provides additional hints and information for message
   608  // transmission.
   609  type Options struct {
   610  	// Last indicates whether this write is the last piece for
   611  	// this stream.
   612  	Last bool
   613  }
   614  
   615  // CallHdr carries the information of a particular RPC.
   616  type CallHdr struct {
   617  	// Host specifies the peer's host.
   618  	Host string
   619  
   620  	// Method specifies the operation to perform.
   621  	Method string
   622  
   623  	// SendCompress specifies the compression algorithm applied on
   624  	// outbound message.
   625  	SendCompress string
   626  
   627  	// ContentSubtype specifies the content-subtype for a request. For example, a
   628  	// content-subtype of "proto" will result in a content-type of
   629  	// "application/grpc+proto". The value of ContentSubtype must be all
   630  	// lowercase, otherwise the behavior is undefined. See
   631  	// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
   632  	// for more details.
   633  	ContentSubtype string
   634  
   635  	PreviousAttempts int // value of grpc-previous-rpc-attempts header to set
   636  }
   637  
   638  // IsActive is the interface that exposing the underlying connection's active status.
   639  type IsActive interface {
   640  	IsActive() bool
   641  }
   642  
   643  // ClientTransport is the common interface for all gRPC client-side transport
   644  // implementations.
   645  type ClientTransport interface {
   646  	// Close tears down this transport. Once it returns, the transport
   647  	// should not be accessed any more. The caller must make sure this
   648  	// is called only once.
   649  	Close() error
   650  
   651  	// GracefulClose starts to tear down the transport: the transport will stop
   652  	// accepting new RPCs and NewStream will return error. Once all streams are
   653  	// finished, the transport will close.
   654  	//
   655  	// It does not block.
   656  	GracefulClose()
   657  
   658  	// Write sends the data for the given stream. A nil stream indicates
   659  	// the write is to be performed on the transport as a whole.
   660  	Write(s *Stream, hdr, data []byte, opts *Options) error
   661  
   662  	// NewStream creates a Stream for an RPC.
   663  	NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error)
   664  
   665  	// CloseStream clears the footprint of a stream when the stream is
   666  	// not needed any more. The err indicates the error incurred when
   667  	// CloseStream is called. Must be called when a stream is finished
   668  	// unless the associated transport is closing.
   669  	CloseStream(stream *Stream, err error)
   670  
   671  	// Error returns a channel that is closed when some I/O error
   672  	// happens. Typically the caller should have a goroutine to monitor
   673  	// this in order to take action (e.g., close the current transport
   674  	// and create a new one) in error case. It should not return nil
   675  	// once the transport is initiated.
   676  	Error() <-chan struct{}
   677  
   678  	// GoAway returns a channel that is closed when ClientTransport
   679  	// receives the draining signal from the server (e.g., GOAWAY frame in
   680  	// HTTP/2).
   681  	GoAway() <-chan struct{}
   682  
   683  	// GetGoAwayReason returns the reason why GoAway frame was received.
   684  	GetGoAwayReason() GoAwayReason
   685  
   686  	// RemoteAddr returns the remote network address.
   687  	RemoteAddr() net.Addr
   688  	LocalAddr() net.Addr
   689  }
   690  
   691  // ServerTransport is the common interface for all gRPC server-side transport
   692  // implementations.
   693  //
   694  // Methods may be called concurrently from multiple goroutines, but
   695  // Write methods for a given Stream will be called serially.
   696  type ServerTransport interface {
   697  	// HandleStreams receives incoming streams using the given handler.
   698  	HandleStreams(func(*Stream), func(context.Context, string) context.Context)
   699  
   700  	// WriteHeader sends the header metadata for the given stream.
   701  	// WriteHeader may not be called on all streams.
   702  	WriteHeader(s *Stream, md metadata.MD) error
   703  
   704  	// Write sends the data for the given stream.
   705  	// Write may not be called on all streams.
   706  	Write(s *Stream, hdr, data []byte, opts *Options) error
   707  
   708  	// WriteStatus sends the status of a stream to the client.  WriteStatus is
   709  	// the final call made on a stream and always occurs.
   710  	WriteStatus(s *Stream, st *status.Status) error
   711  
   712  	// Close tears down the transport. Once it is called, the transport
   713  	// should not be accessed any more. All the pending streams and their
   714  	// handlers will be terminated asynchronously.
   715  	Close() error
   716  
   717  	// RemoteAddr returns the remote network address.
   718  	RemoteAddr() net.Addr
   719  	LocalAddr() net.Addr
   720  
   721  	// Drain notifies the client this ServerTransport stops accepting new RPCs.
   722  	Drain()
   723  }
   724  
   725  // connectionErrorf creates an ConnectionError with the specified error description.
   726  func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
   727  	return ConnectionError{
   728  		Desc: fmt.Sprintf(format, a...),
   729  		temp: temp,
   730  		err:  e,
   731  	}
   732  }
   733  
   734  // ConnectionError is an error that results in the termination of the
   735  // entire connection and the retry of all the active streams.
   736  type ConnectionError struct {
   737  	Desc string
   738  	temp bool
   739  	err  error
   740  }
   741  
   742  func (e ConnectionError) Error() string {
   743  	return fmt.Sprintf("connection error: desc = %q", e.Desc)
   744  }
   745  
   746  // Temporary indicates if this connection error is temporary or fatal.
   747  func (e ConnectionError) Temporary() bool {
   748  	return e.temp
   749  }
   750  
   751  // Origin returns the original error of this connection error.
   752  func (e ConnectionError) Origin() error {
   753  	// Never return nil error here.
   754  	// If the original error is nil, return itself.
   755  	if e.err == nil {
   756  		return e
   757  	}
   758  	return e.err
   759  }
   760  
   761  var (
   762  	// ErrConnClosing indicates that the transport is closing.
   763  	ErrConnClosing = connectionErrorf(true, nil, "transport is closing")
   764  
   765  	// errStreamDone is returned from write at the client side to indicate application
   766  	// layer of an error.
   767  	errStreamDone = errors.New("the stream is done")
   768  
   769  	// errStreamDrain indicates that the stream is rejected because the
   770  	// connection is draining. This could be caused by goaway or balancer
   771  	// removing the address.
   772  	errStreamDrain = status.New(codes.Unavailable, "the connection is draining").Err()
   773  
   774  	// StatusGoAway indicates that the server sent a GOAWAY that included this
   775  	// stream's ID in unprocessed RPCs.
   776  	statusGoAway = status.New(codes.Unavailable, "the stream is rejected because server is draining the connection")
   777  )
   778  
   779  // GoAwayReason contains the reason for the GoAway frame received.
   780  type GoAwayReason uint8
   781  
   782  const (
   783  	// GoAwayInvalid indicates that no GoAway frame is received.
   784  	GoAwayInvalid GoAwayReason = 0
   785  	// GoAwayNoReason is the default value when GoAway frame is received.
   786  	GoAwayNoReason GoAwayReason = 1
   787  	// GoAwayTooManyPings indicates that a GoAway frame with
   788  	// ErrCodeEnhanceYourCalm was received and that the debug data said
   789  	// "too_many_pings".
   790  	GoAwayTooManyPings GoAwayReason = 2
   791  )
   792  
   793  // ContextErr converts the error from context package into a status error.
   794  func ContextErr(err error) error {
   795  	switch err {
   796  	case context.DeadlineExceeded:
   797  		return status.New(codes.DeadlineExceeded, err.Error()).Err()
   798  	case context.Canceled:
   799  		return status.New(codes.Canceled, err.Error()).Err()
   800  	}
   801  	return status.Errorf(codes.Internal, "Unexpected error from context packet: %v", err)
   802  }
   803  
   804  // IsStreamDoneErr returns true if the error indicates that the stream is done.
   805  func IsStreamDoneErr(err error) bool {
   806  	return errors.Is(err, errStreamDone)
   807  }
   808  
   809  // TLSConfig checks and supplement the tls config provided by user.
   810  func TLSConfig(tlsConfig *tls.Config) *tls.Config {
   811  	cfg := tlsConfig.Clone()
   812  	// When multiple application protocols are supported on a single server-side port number,
   813  	// the client and the server need to negotiate an application protocol for use with each connection.
   814  	// For gRPC, "h2" should be appended to "application_layer_protocol_negotiation" field.
   815  	cfg.NextProtos = tlsAppendH2ToALPNProtocols(cfg.NextProtos)
   816  
   817  	// Implementations of HTTP/2 MUST use TLS version 1.2 [TLS12] or higher for HTTP/2 over TLS.
   818  	// https://datatracker.ietf.org/doc/html/rfc7540#section-9.2
   819  	if cfg.MinVersion == 0 && (cfg.MaxVersion == 0 || cfg.MaxVersion >= tls.VersionTLS12) {
   820  		cfg.MinVersion = tls.VersionTLS12
   821  	}
   822  	return cfg
   823  }
   824  
   825  const alpnProtoStrH2 = "h2"
   826  
   827  func tlsAppendH2ToALPNProtocols(ps []string) []string {
   828  	for _, p := range ps {
   829  		if p == alpnProtoStrH2 {
   830  			return ps
   831  		}
   832  	}
   833  	ret := make([]string, 0, len(ps)+1)
   834  	ret = append(ret, ps...)
   835  	return append(ret, alpnProtoStrH2)
   836  }