google.golang.org/grpc@v1.74.2/internal/transport/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   */
    18  
    19  // Package transport defines and implements message oriented communication
    20  // channel to complete various transactions (e.g., an RPC).  It is meant for
    21  // grpc-internal usage and is not intended to be imported directly by users.
    22  package transport
    23  
    24  import (
    25  	"context"
    26  	"errors"
    27  	"fmt"
    28  	"io"
    29  	"net"
    30  	"sync"
    31  	"sync/atomic"
    32  	"time"
    33  
    34  	"google.golang.org/grpc/codes"
    35  	"google.golang.org/grpc/credentials"
    36  	"google.golang.org/grpc/internal/channelz"
    37  	"google.golang.org/grpc/keepalive"
    38  	"google.golang.org/grpc/mem"
    39  	"google.golang.org/grpc/metadata"
    40  	"google.golang.org/grpc/peer"
    41  	"google.golang.org/grpc/stats"
    42  	"google.golang.org/grpc/status"
    43  	"google.golang.org/grpc/tap"
    44  )
    45  
    46  const logLevel = 2
    47  
    48  // recvMsg represents the received msg from the transport. All transport
    49  // protocol specific info has been removed.
    50  type recvMsg struct {
    51  	buffer mem.Buffer
    52  	// nil: received some data
    53  	// io.EOF: stream is completed. data is nil.
    54  	// other non-nil error: transport failure. data is nil.
    55  	err error
    56  }
    57  
    58  // recvBuffer is an unbounded channel of recvMsg structs.
    59  //
    60  // Note: recvBuffer differs from buffer.Unbounded only in the fact that it
    61  // holds a channel of recvMsg structs instead of objects implementing "item"
    62  // interface. recvBuffer is written to much more often and using strict recvMsg
    63  // structs helps avoid allocation in "recvBuffer.put"
    64  type recvBuffer struct {
    65  	c       chan recvMsg
    66  	mu      sync.Mutex
    67  	backlog []recvMsg
    68  	err     error
    69  }
    70  
    71  func newRecvBuffer() *recvBuffer {
    72  	b := &recvBuffer{
    73  		c: make(chan recvMsg, 1),
    74  	}
    75  	return b
    76  }
    77  
    78  func (b *recvBuffer) put(r recvMsg) {
    79  	b.mu.Lock()
    80  	if b.err != nil {
    81  		// drop the buffer on the floor. Since b.err is not nil, any subsequent reads
    82  		// will always return an error, making this buffer inaccessible.
    83  		r.buffer.Free()
    84  		b.mu.Unlock()
    85  		// An error had occurred earlier, don't accept more
    86  		// data or errors.
    87  		return
    88  	}
    89  	b.err = r.err
    90  	if len(b.backlog) == 0 {
    91  		select {
    92  		case b.c <- r:
    93  			b.mu.Unlock()
    94  			return
    95  		default:
    96  		}
    97  	}
    98  	b.backlog = append(b.backlog, r)
    99  	b.mu.Unlock()
   100  }
   101  
   102  func (b *recvBuffer) load() {
   103  	b.mu.Lock()
   104  	if len(b.backlog) > 0 {
   105  		select {
   106  		case b.c <- b.backlog[0]:
   107  			b.backlog[0] = recvMsg{}
   108  			b.backlog = b.backlog[1:]
   109  		default:
   110  		}
   111  	}
   112  	b.mu.Unlock()
   113  }
   114  
   115  // get returns the channel that receives a recvMsg in the buffer.
   116  //
   117  // Upon receipt of a recvMsg, the caller should call load to send another
   118  // recvMsg onto the channel if there is any.
   119  func (b *recvBuffer) get() <-chan recvMsg {
   120  	return b.c
   121  }
   122  
   123  // recvBufferReader implements io.Reader interface to read the data from
   124  // recvBuffer.
   125  type recvBufferReader struct {
   126  	closeStream func(error) // Closes the client transport stream with the given error and nil trailer metadata.
   127  	ctx         context.Context
   128  	ctxDone     <-chan struct{} // cache of ctx.Done() (for performance).
   129  	recv        *recvBuffer
   130  	last        mem.Buffer // Stores the remaining data in the previous calls.
   131  	err         error
   132  }
   133  
   134  func (r *recvBufferReader) ReadMessageHeader(header []byte) (n int, err error) {
   135  	if r.err != nil {
   136  		return 0, r.err
   137  	}
   138  	if r.last != nil {
   139  		n, r.last = mem.ReadUnsafe(header, r.last)
   140  		return n, nil
   141  	}
   142  	if r.closeStream != nil {
   143  		n, r.err = r.readMessageHeaderClient(header)
   144  	} else {
   145  		n, r.err = r.readMessageHeader(header)
   146  	}
   147  	return n, r.err
   148  }
   149  
   150  // Read reads the next n bytes from last. If last is drained, it tries to read
   151  // additional data from recv. It blocks if there no additional data available in
   152  // recv. If Read returns any non-nil error, it will continue to return that
   153  // error.
   154  func (r *recvBufferReader) Read(n int) (buf mem.Buffer, err error) {
   155  	if r.err != nil {
   156  		return nil, r.err
   157  	}
   158  	if r.last != nil {
   159  		buf = r.last
   160  		if r.last.Len() > n {
   161  			buf, r.last = mem.SplitUnsafe(buf, n)
   162  		} else {
   163  			r.last = nil
   164  		}
   165  		return buf, nil
   166  	}
   167  	if r.closeStream != nil {
   168  		buf, r.err = r.readClient(n)
   169  	} else {
   170  		buf, r.err = r.read(n)
   171  	}
   172  	return buf, r.err
   173  }
   174  
   175  func (r *recvBufferReader) readMessageHeader(header []byte) (n int, err error) {
   176  	select {
   177  	case <-r.ctxDone:
   178  		return 0, ContextErr(r.ctx.Err())
   179  	case m := <-r.recv.get():
   180  		return r.readMessageHeaderAdditional(m, header)
   181  	}
   182  }
   183  
   184  func (r *recvBufferReader) read(n int) (buf mem.Buffer, err error) {
   185  	select {
   186  	case <-r.ctxDone:
   187  		return nil, ContextErr(r.ctx.Err())
   188  	case m := <-r.recv.get():
   189  		return r.readAdditional(m, n)
   190  	}
   191  }
   192  
   193  func (r *recvBufferReader) readMessageHeaderClient(header []byte) (n int, err error) {
   194  	// If the context is canceled, then closes the stream with nil metadata.
   195  	// closeStream writes its error parameter to r.recv as a recvMsg.
   196  	// r.readAdditional acts on that message and returns the necessary error.
   197  	select {
   198  	case <-r.ctxDone:
   199  		// Note that this adds the ctx error to the end of recv buffer, and
   200  		// reads from the head. This will delay the error until recv buffer is
   201  		// empty, thus will delay ctx cancellation in Recv().
   202  		//
   203  		// It's done this way to fix a race between ctx cancel and trailer. The
   204  		// race was, stream.Recv() may return ctx error if ctxDone wins the
   205  		// race, but stream.Trailer() may return a non-nil md because the stream
   206  		// was not marked as done when trailer is received. This closeStream
   207  		// call will mark stream as done, thus fix the race.
   208  		//
   209  		// TODO: delaying ctx error seems like a unnecessary side effect. What
   210  		// we really want is to mark the stream as done, and return ctx error
   211  		// faster.
   212  		r.closeStream(ContextErr(r.ctx.Err()))
   213  		m := <-r.recv.get()
   214  		return r.readMessageHeaderAdditional(m, header)
   215  	case m := <-r.recv.get():
   216  		return r.readMessageHeaderAdditional(m, header)
   217  	}
   218  }
   219  
   220  func (r *recvBufferReader) readClient(n int) (buf mem.Buffer, err error) {
   221  	// If the context is canceled, then closes the stream with nil metadata.
   222  	// closeStream writes its error parameter to r.recv as a recvMsg.
   223  	// r.readAdditional acts on that message and returns the necessary error.
   224  	select {
   225  	case <-r.ctxDone:
   226  		// Note that this adds the ctx error to the end of recv buffer, and
   227  		// reads from the head. This will delay the error until recv buffer is
   228  		// empty, thus will delay ctx cancellation in Recv().
   229  		//
   230  		// It's done this way to fix a race between ctx cancel and trailer. The
   231  		// race was, stream.Recv() may return ctx error if ctxDone wins the
   232  		// race, but stream.Trailer() may return a non-nil md because the stream
   233  		// was not marked as done when trailer is received. This closeStream
   234  		// call will mark stream as done, thus fix the race.
   235  		//
   236  		// TODO: delaying ctx error seems like a unnecessary side effect. What
   237  		// we really want is to mark the stream as done, and return ctx error
   238  		// faster.
   239  		r.closeStream(ContextErr(r.ctx.Err()))
   240  		m := <-r.recv.get()
   241  		return r.readAdditional(m, n)
   242  	case m := <-r.recv.get():
   243  		return r.readAdditional(m, n)
   244  	}
   245  }
   246  
   247  func (r *recvBufferReader) readMessageHeaderAdditional(m recvMsg, header []byte) (n int, err error) {
   248  	r.recv.load()
   249  	if m.err != nil {
   250  		if m.buffer != nil {
   251  			m.buffer.Free()
   252  		}
   253  		return 0, m.err
   254  	}
   255  
   256  	n, r.last = mem.ReadUnsafe(header, m.buffer)
   257  
   258  	return n, nil
   259  }
   260  
   261  func (r *recvBufferReader) readAdditional(m recvMsg, n int) (b mem.Buffer, err error) {
   262  	r.recv.load()
   263  	if m.err != nil {
   264  		if m.buffer != nil {
   265  			m.buffer.Free()
   266  		}
   267  		return nil, m.err
   268  	}
   269  
   270  	if m.buffer.Len() > n {
   271  		m.buffer, r.last = mem.SplitUnsafe(m.buffer, n)
   272  	}
   273  
   274  	return m.buffer, nil
   275  }
   276  
   277  type streamState uint32
   278  
   279  const (
   280  	streamActive    streamState = iota
   281  	streamWriteDone             // EndStream sent
   282  	streamReadDone              // EndStream received
   283  	streamDone                  // the entire stream is finished.
   284  )
   285  
   286  // Stream represents an RPC in the transport layer.
   287  type Stream struct {
   288  	id           uint32
   289  	ctx          context.Context // the associated context of the stream
   290  	method       string          // the associated RPC method of the stream
   291  	recvCompress string
   292  	sendCompress string
   293  	buf          *recvBuffer
   294  	trReader     *transportReader
   295  	fc           *inFlow
   296  	wq           *writeQuota
   297  
   298  	// Callback to state application's intentions to read data. This
   299  	// is used to adjust flow control, if needed.
   300  	requestRead func(int)
   301  
   302  	state streamState
   303  
   304  	// contentSubtype is the content-subtype for requests.
   305  	// this must be lowercase or the behavior is undefined.
   306  	contentSubtype string
   307  
   308  	trailer metadata.MD // the key-value map of trailer metadata.
   309  }
   310  
   311  func (s *Stream) swapState(st streamState) streamState {
   312  	return streamState(atomic.SwapUint32((*uint32)(&s.state), uint32(st)))
   313  }
   314  
   315  func (s *Stream) compareAndSwapState(oldState, newState streamState) bool {
   316  	return atomic.CompareAndSwapUint32((*uint32)(&s.state), uint32(oldState), uint32(newState))
   317  }
   318  
   319  func (s *Stream) getState() streamState {
   320  	return streamState(atomic.LoadUint32((*uint32)(&s.state)))
   321  }
   322  
   323  // Trailer returns the cached trailer metadata. Note that if it is not called
   324  // after the entire stream is done, it could return an empty MD.
   325  // It can be safely read only after stream has ended that is either read
   326  // or write have returned io.EOF.
   327  func (s *Stream) Trailer() metadata.MD {
   328  	return s.trailer.Copy()
   329  }
   330  
   331  // Context returns the context of the stream.
   332  func (s *Stream) Context() context.Context {
   333  	return s.ctx
   334  }
   335  
   336  // Method returns the method for the stream.
   337  func (s *Stream) Method() string {
   338  	return s.method
   339  }
   340  
   341  func (s *Stream) write(m recvMsg) {
   342  	s.buf.put(m)
   343  }
   344  
   345  // ReadMessageHeader reads data into the provided header slice from the stream.
   346  // It first checks if there was an error during a previous read operation and
   347  // returns it if present. It then requests a read operation for the length of
   348  // the header. It continues to read from the stream until the entire header
   349  // slice is filled or an error occurs. If an `io.EOF` error is encountered with
   350  // partially read data, it is converted to `io.ErrUnexpectedEOF` to indicate an
   351  // unexpected end of the stream. The method returns any error encountered during
   352  // the read process or nil if the header was successfully read.
   353  func (s *Stream) ReadMessageHeader(header []byte) (err error) {
   354  	// Don't request a read if there was an error earlier
   355  	if er := s.trReader.er; er != nil {
   356  		return er
   357  	}
   358  	s.requestRead(len(header))
   359  	for len(header) != 0 {
   360  		n, err := s.trReader.ReadMessageHeader(header)
   361  		header = header[n:]
   362  		if len(header) == 0 {
   363  			err = nil
   364  		}
   365  		if err != nil {
   366  			if n > 0 && err == io.EOF {
   367  				err = io.ErrUnexpectedEOF
   368  			}
   369  			return err
   370  		}
   371  	}
   372  	return nil
   373  }
   374  
   375  // Read reads n bytes from the wire for this stream.
   376  func (s *Stream) read(n int) (data mem.BufferSlice, err error) {
   377  	// Don't request a read if there was an error earlier
   378  	if er := s.trReader.er; er != nil {
   379  		return nil, er
   380  	}
   381  	s.requestRead(n)
   382  	for n != 0 {
   383  		buf, err := s.trReader.Read(n)
   384  		var bufLen int
   385  		if buf != nil {
   386  			bufLen = buf.Len()
   387  		}
   388  		n -= bufLen
   389  		if n == 0 {
   390  			err = nil
   391  		}
   392  		if err != nil {
   393  			if bufLen > 0 && err == io.EOF {
   394  				err = io.ErrUnexpectedEOF
   395  			}
   396  			data.Free()
   397  			return nil, err
   398  		}
   399  		data = append(data, buf)
   400  	}
   401  	return data, nil
   402  }
   403  
   404  // transportReader reads all the data available for this Stream from the transport and
   405  // passes them into the decoder, which converts them into a gRPC message stream.
   406  // The error is io.EOF when the stream is done or another non-nil error if
   407  // the stream broke.
   408  type transportReader struct {
   409  	reader *recvBufferReader
   410  	// The handler to control the window update procedure for both this
   411  	// particular stream and the associated transport.
   412  	windowHandler func(int)
   413  	er            error
   414  }
   415  
   416  func (t *transportReader) ReadMessageHeader(header []byte) (int, error) {
   417  	n, err := t.reader.ReadMessageHeader(header)
   418  	if err != nil {
   419  		t.er = err
   420  		return 0, err
   421  	}
   422  	t.windowHandler(n)
   423  	return n, nil
   424  }
   425  
   426  func (t *transportReader) Read(n int) (mem.Buffer, error) {
   427  	buf, err := t.reader.Read(n)
   428  	if err != nil {
   429  		t.er = err
   430  		return buf, err
   431  	}
   432  	t.windowHandler(buf.Len())
   433  	return buf, nil
   434  }
   435  
   436  // GoString is implemented by Stream so context.String() won't
   437  // race when printing %#v.
   438  func (s *Stream) GoString() string {
   439  	return fmt.Sprintf("<stream: %p, %v>", s, s.method)
   440  }
   441  
   442  // state of transport
   443  type transportState int
   444  
   445  const (
   446  	reachable transportState = iota
   447  	closing
   448  	draining
   449  )
   450  
   451  // ServerConfig consists of all the configurations to establish a server transport.
   452  type ServerConfig struct {
   453  	MaxStreams            uint32
   454  	ConnectionTimeout     time.Duration
   455  	Credentials           credentials.TransportCredentials
   456  	InTapHandle           tap.ServerInHandle
   457  	StatsHandlers         []stats.Handler
   458  	KeepaliveParams       keepalive.ServerParameters
   459  	KeepalivePolicy       keepalive.EnforcementPolicy
   460  	InitialWindowSize     int32
   461  	InitialConnWindowSize int32
   462  	WriteBufferSize       int
   463  	ReadBufferSize        int
   464  	SharedWriteBuffer     bool
   465  	ChannelzParent        *channelz.Server
   466  	MaxHeaderListSize     *uint32
   467  	HeaderTableSize       *uint32
   468  	BufferPool            mem.BufferPool
   469  	StaticWindowSize      bool
   470  }
   471  
   472  // ConnectOptions covers all relevant options for communicating with the server.
   473  type ConnectOptions struct {
   474  	// UserAgent is the application user agent.
   475  	UserAgent string
   476  	// Dialer specifies how to dial a network address.
   477  	Dialer func(context.Context, string) (net.Conn, error)
   478  	// FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors.
   479  	FailOnNonTempDialError bool
   480  	// PerRPCCredentials stores the PerRPCCredentials required to issue RPCs.
   481  	PerRPCCredentials []credentials.PerRPCCredentials
   482  	// TransportCredentials stores the Authenticator required to setup a client
   483  	// connection. Only one of TransportCredentials and CredsBundle is non-nil.
   484  	TransportCredentials credentials.TransportCredentials
   485  	// CredsBundle is the credentials bundle to be used. Only one of
   486  	// TransportCredentials and CredsBundle is non-nil.
   487  	CredsBundle credentials.Bundle
   488  	// KeepaliveParams stores the keepalive parameters.
   489  	KeepaliveParams keepalive.ClientParameters
   490  	// StatsHandlers stores the handler for stats.
   491  	StatsHandlers []stats.Handler
   492  	// InitialWindowSize sets the initial window size for a stream.
   493  	InitialWindowSize int32
   494  	// InitialConnWindowSize sets the initial window size for a connection.
   495  	InitialConnWindowSize int32
   496  	// WriteBufferSize sets the size of write buffer which in turn determines how much data can be batched before it's written on the wire.
   497  	WriteBufferSize int
   498  	// ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall.
   499  	ReadBufferSize int
   500  	// SharedWriteBuffer indicates whether connections should reuse write buffer
   501  	SharedWriteBuffer bool
   502  	// ChannelzParent sets the addrConn id which initiated the creation of this client transport.
   503  	ChannelzParent *channelz.SubChannel
   504  	// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
   505  	MaxHeaderListSize *uint32
   506  	// The mem.BufferPool to use when reading/writing to the wire.
   507  	BufferPool mem.BufferPool
   508  	// StaticWindowSize controls whether dynamic window sizing is enabled.
   509  	StaticWindowSize bool
   510  }
   511  
   512  // WriteOptions provides additional hints and information for message
   513  // transmission.
   514  type WriteOptions struct {
   515  	// Last indicates whether this write is the last piece for
   516  	// this stream.
   517  	Last bool
   518  }
   519  
   520  // CallHdr carries the information of a particular RPC.
   521  type CallHdr struct {
   522  	// Host specifies the peer's host.
   523  	Host string
   524  
   525  	// Method specifies the operation to perform.
   526  	Method string
   527  
   528  	// SendCompress specifies the compression algorithm applied on
   529  	// outbound message.
   530  	SendCompress string
   531  
   532  	// Creds specifies credentials.PerRPCCredentials for a call.
   533  	Creds credentials.PerRPCCredentials
   534  
   535  	// ContentSubtype specifies the content-subtype for a request. For example, a
   536  	// content-subtype of "proto" will result in a content-type of
   537  	// "application/grpc+proto". The value of ContentSubtype must be all
   538  	// lowercase, otherwise the behavior is undefined. See
   539  	// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
   540  	// for more details.
   541  	ContentSubtype string
   542  
   543  	PreviousAttempts int // value of grpc-previous-rpc-attempts header to set
   544  
   545  	DoneFunc func() // called when the stream is finished
   546  
   547  	// Authority is used to explicitly override the `:authority` header. If set,
   548  	// this value takes precedence over the Host field and will be used as the
   549  	// value for the `:authority` header.
   550  	Authority string
   551  }
   552  
   553  // ClientTransport is the common interface for all gRPC client-side transport
   554  // implementations.
   555  type ClientTransport interface {
   556  	// Close tears down this transport. Once it returns, the transport
   557  	// should not be accessed any more. The caller must make sure this
   558  	// is called only once.
   559  	Close(err error)
   560  
   561  	// GracefulClose starts to tear down the transport: the transport will stop
   562  	// accepting new RPCs and NewStream will return error. Once all streams are
   563  	// finished, the transport will close.
   564  	//
   565  	// It does not block.
   566  	GracefulClose()
   567  
   568  	// NewStream creates a Stream for an RPC.
   569  	NewStream(ctx context.Context, callHdr *CallHdr) (*ClientStream, error)
   570  
   571  	// Error returns a channel that is closed when some I/O error
   572  	// happens. Typically the caller should have a goroutine to monitor
   573  	// this in order to take action (e.g., close the current transport
   574  	// and create a new one) in error case. It should not return nil
   575  	// once the transport is initiated.
   576  	Error() <-chan struct{}
   577  
   578  	// GoAway returns a channel that is closed when ClientTransport
   579  	// receives the draining signal from the server (e.g., GOAWAY frame in
   580  	// HTTP/2).
   581  	GoAway() <-chan struct{}
   582  
   583  	// GetGoAwayReason returns the reason why GoAway frame was received, along
   584  	// with a human readable string with debug info.
   585  	GetGoAwayReason() (GoAwayReason, string)
   586  
   587  	// RemoteAddr returns the remote network address.
   588  	RemoteAddr() net.Addr
   589  }
   590  
   591  // ServerTransport is the common interface for all gRPC server-side transport
   592  // implementations.
   593  //
   594  // Methods may be called concurrently from multiple goroutines, but
   595  // Write methods for a given Stream will be called serially.
   596  type ServerTransport interface {
   597  	// HandleStreams receives incoming streams using the given handler.
   598  	HandleStreams(context.Context, func(*ServerStream))
   599  
   600  	// Close tears down the transport. Once it is called, the transport
   601  	// should not be accessed any more. All the pending streams and their
   602  	// handlers will be terminated asynchronously.
   603  	Close(err error)
   604  
   605  	// Peer returns the peer of the server transport.
   606  	Peer() *peer.Peer
   607  
   608  	// Drain notifies the client this ServerTransport stops accepting new RPCs.
   609  	Drain(debugData string)
   610  }
   611  
   612  type internalServerTransport interface {
   613  	ServerTransport
   614  	writeHeader(s *ServerStream, md metadata.MD) error
   615  	write(s *ServerStream, hdr []byte, data mem.BufferSlice, opts *WriteOptions) error
   616  	writeStatus(s *ServerStream, st *status.Status) error
   617  	incrMsgRecv()
   618  }
   619  
   620  // connectionErrorf creates an ConnectionError with the specified error description.
   621  func connectionErrorf(temp bool, e error, format string, a ...any) ConnectionError {
   622  	return ConnectionError{
   623  		Desc: fmt.Sprintf(format, a...),
   624  		temp: temp,
   625  		err:  e,
   626  	}
   627  }
   628  
   629  // ConnectionError is an error that results in the termination of the
   630  // entire connection and the retry of all the active streams.
   631  type ConnectionError struct {
   632  	Desc string
   633  	temp bool
   634  	err  error
   635  }
   636  
   637  func (e ConnectionError) Error() string {
   638  	return fmt.Sprintf("connection error: desc = %q", e.Desc)
   639  }
   640  
   641  // Temporary indicates if this connection error is temporary or fatal.
   642  func (e ConnectionError) Temporary() bool {
   643  	return e.temp
   644  }
   645  
   646  // Origin returns the original error of this connection error.
   647  func (e ConnectionError) Origin() error {
   648  	// Never return nil error here.
   649  	// If the original error is nil, return itself.
   650  	if e.err == nil {
   651  		return e
   652  	}
   653  	return e.err
   654  }
   655  
   656  // Unwrap returns the original error of this connection error or nil when the
   657  // origin is nil.
   658  func (e ConnectionError) Unwrap() error {
   659  	return e.err
   660  }
   661  
   662  var (
   663  	// ErrConnClosing indicates that the transport is closing.
   664  	ErrConnClosing = connectionErrorf(true, nil, "transport is closing")
   665  	// errStreamDrain indicates that the stream is rejected because the
   666  	// connection is draining. This could be caused by goaway or balancer
   667  	// removing the address.
   668  	errStreamDrain = status.Error(codes.Unavailable, "the connection is draining")
   669  	// errStreamDone is returned from write at the client side to indicate application
   670  	// layer of an error.
   671  	errStreamDone = errors.New("the stream is done")
   672  	// StatusGoAway indicates that the server sent a GOAWAY that included this
   673  	// stream's ID in unprocessed RPCs.
   674  	statusGoAway = status.New(codes.Unavailable, "the stream is rejected because server is draining the connection")
   675  )
   676  
   677  // GoAwayReason contains the reason for the GoAway frame received.
   678  type GoAwayReason uint8
   679  
   680  const (
   681  	// GoAwayInvalid indicates that no GoAway frame is received.
   682  	GoAwayInvalid GoAwayReason = 0
   683  	// GoAwayNoReason is the default value when GoAway frame is received.
   684  	GoAwayNoReason GoAwayReason = 1
   685  	// GoAwayTooManyPings indicates that a GoAway frame with
   686  	// ErrCodeEnhanceYourCalm was received and that the debug data said
   687  	// "too_many_pings".
   688  	GoAwayTooManyPings GoAwayReason = 2
   689  )
   690  
   691  // ContextErr converts the error from context package into a status error.
   692  func ContextErr(err error) error {
   693  	switch err {
   694  	case context.DeadlineExceeded:
   695  		return status.Error(codes.DeadlineExceeded, err.Error())
   696  	case context.Canceled:
   697  		return status.Error(codes.Canceled, err.Error())
   698  	}
   699  	return status.Errorf(codes.Internal, "Unexpected error from context packet: %v", err)
   700  }