3
* Copyright 2014 gRPC authors.
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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
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.
34
"google.golang.org/grpc/codes"
35
"google.golang.org/grpc/credentials"
36
"google.golang.org/grpc/keepalive"
37
"google.golang.org/grpc/metadata"
38
"google.golang.org/grpc/resolver"
39
"google.golang.org/grpc/stats"
40
"google.golang.org/grpc/status"
41
"google.golang.org/grpc/tap"
46
type bufferPool struct {
50
func newBufferPool() *bufferPool {
53
New: func() interface{} {
54
return new(bytes.Buffer)
60
func (p *bufferPool) get() *bytes.Buffer {
61
return p.pool.Get().(*bytes.Buffer)
64
func (p *bufferPool) put(b *bytes.Buffer) {
68
// recvMsg represents the received msg from the transport. All transport
69
// protocol specific info has been removed.
72
// nil: received some data
73
// io.EOF: stream is completed. data is nil.
74
// other non-nil error: transport failure. data is nil.
78
// recvBuffer is an unbounded channel of recvMsg structs.
80
// Note: recvBuffer differs from buffer.Unbounded only in the fact that it
81
// holds a channel of recvMsg structs instead of objects implementing "item"
82
// interface. recvBuffer is written to much more often and using strict recvMsg
83
// structs helps avoid allocation in "recvBuffer.put"
84
type recvBuffer struct {
91
func newRecvBuffer() *recvBuffer {
93
c: make(chan recvMsg, 1),
98
func (b *recvBuffer) put(r recvMsg) {
102
// An error had occurred earlier, don't accept more
107
if len(b.backlog) == 0 {
115
b.backlog = append(b.backlog, r)
119
func (b *recvBuffer) load() {
121
if len(b.backlog) > 0 {
123
case b.c <- b.backlog[0]:
124
b.backlog[0] = recvMsg{}
125
b.backlog = b.backlog[1:]
132
// get returns the channel that receives a recvMsg in the buffer.
134
// Upon receipt of a recvMsg, the caller should call load to send another
135
// recvMsg onto the channel if there is any.
136
func (b *recvBuffer) get() <-chan recvMsg {
140
// recvBufferReader implements io.Reader interface to read the data from
142
type recvBufferReader struct {
143
closeStream func(error) // Closes the client transport stream with the given error and nil trailer metadata.
145
ctxDone <-chan struct{} // cache of ctx.Done() (for performance).
147
last *bytes.Buffer // Stores the remaining data in the previous calls.
149
freeBuffer func(*bytes.Buffer)
152
// Read reads the next len(p) bytes from last. If last is drained, it tries to
153
// read additional data from recv. It blocks if there no additional data available
154
// in recv. If Read returns any non-nil error, it will continue to return that error.
155
func (r *recvBufferReader) Read(p []byte) (n int, err error) {
160
// Read remaining data left in last call.
161
copied, _ := r.last.Read(p)
162
if r.last.Len() == 0 {
168
if r.closeStream != nil {
169
n, r.err = r.readClient(p)
176
func (r *recvBufferReader) read(p []byte) (n int, err error) {
179
return 0, ContextErr(r.ctx.Err())
180
case m := <-r.recv.get():
181
return r.readAdditional(m, p)
185
func (r *recvBufferReader) readClient(p []byte) (n int, err error) {
186
// If the context is canceled, then closes the stream with nil metadata.
187
// closeStream writes its error parameter to r.recv as a recvMsg.
188
// r.readAdditional acts on that message and returns the necessary error.
191
// Note that this adds the ctx error to the end of recv buffer, and
192
// reads from the head. This will delay the error until recv buffer is
193
// empty, thus will delay ctx cancellation in Recv().
195
// It's done this way to fix a race between ctx cancel and trailer. The
196
// race was, stream.Recv() may return ctx error if ctxDone wins the
197
// race, but stream.Trailer() may return a non-nil md because the stream
198
// was not marked as done when trailer is received. This closeStream
199
// call will mark stream as done, thus fix the race.
201
// TODO: delaying ctx error seems like a unnecessary side effect. What
202
// we really want is to mark the stream as done, and return ctx error
204
r.closeStream(ContextErr(r.ctx.Err()))
206
return r.readAdditional(m, p)
207
case m := <-r.recv.get():
208
return r.readAdditional(m, p)
212
func (r *recvBufferReader) readAdditional(m recvMsg, p []byte) (n int, err error) {
217
copied, _ := m.buffer.Read(p)
218
if m.buffer.Len() == 0 {
219
r.freeBuffer(m.buffer)
227
type streamState uint32
230
streamActive streamState = iota
231
streamWriteDone // EndStream sent
232
streamReadDone // EndStream received
233
streamDone // the entire stream is finished.
236
// Stream represents an RPC in the transport layer.
239
st ServerTransport // nil for client side Stream
240
ct *http2Client // nil for server side Stream
241
ctx context.Context // the associated context of the stream
242
cancel context.CancelFunc // always nil for client side Stream
243
done chan struct{} // closed at the end of stream to unblock writers. On the client side.
244
ctxDone <-chan struct{} // same as done chan but for server side. Cache of ctx.Done() (for performance)
245
method string // the associated RPC method of the stream
253
// Callback to state application's intentions to read data. This
254
// is used to adjust flow control, if needed.
255
requestRead func(int)
257
headerChan chan struct{} // closed to indicate the end of header metadata.
258
headerChanClosed uint32 // set when headerChan is closed. Used to avoid closing headerChan multiple times.
259
// headerValid indicates whether a valid header was received. Only
260
// meaningful after headerChan is closed (always call waitOnHeader() before
261
// reading its value). Not valid on server side.
264
// hdrMu protects header and trailer metadata on the server-side.
266
// On client side, header keeps the received header metadata.
268
// On server side, header keeps the header set by SetHeader(). The complete
269
// header will merged into this after t.WriteHeader() is called.
271
trailer metadata.MD // the key-value map of trailer metadata.
273
noHeaders bool // set if the client never received headers (set only after the stream is done).
275
// On the server-side, headerSent is atomically set to 1 when the headers are sent out.
280
// On client-side it is the status error received from the server.
281
// On server-side it is unused.
282
status *status.Status
284
bytesReceived uint32 // indicates whether any bytes have been received on this stream
285
unprocessed uint32 // set if the server sends a refused stream or GOAWAY including this stream
287
// contentSubtype is the content-subtype for requests.
288
// this must be lowercase or the behavior is undefined.
289
contentSubtype string
292
// isHeaderSent is only valid on the server-side.
293
func (s *Stream) isHeaderSent() bool {
294
return atomic.LoadUint32(&s.headerSent) == 1
297
// updateHeaderSent updates headerSent and returns true
298
// if it was alreay set. It is valid only on server-side.
299
func (s *Stream) updateHeaderSent() bool {
300
return atomic.SwapUint32(&s.headerSent, 1) == 1
303
func (s *Stream) swapState(st streamState) streamState {
304
return streamState(atomic.SwapUint32((*uint32)(&s.state), uint32(st)))
307
func (s *Stream) compareAndSwapState(oldState, newState streamState) bool {
308
return atomic.CompareAndSwapUint32((*uint32)(&s.state), uint32(oldState), uint32(newState))
311
func (s *Stream) getState() streamState {
312
return streamState(atomic.LoadUint32((*uint32)(&s.state)))
315
func (s *Stream) waitOnHeader() {
316
if s.headerChan == nil {
317
// On the server headerChan is always nil since a stream originates
318
// only after having received headers.
323
// Close the stream to prevent headers/trailers from changing after
324
// this function returns.
325
s.ct.CloseStream(s, ContextErr(s.ctx.Err()))
326
// headerChan could possibly not be closed yet if closeStream raced
327
// with operateHeaders; wait until it is closed explicitly here.
333
// RecvCompress returns the compression algorithm applied to the inbound
334
// message. It is empty string if there is no compression applied.
335
func (s *Stream) RecvCompress() string {
337
return s.recvCompress
340
// SetSendCompress sets the compression algorithm to the stream.
341
func (s *Stream) SetSendCompress(str string) {
345
// Done returns a channel which is closed when it receives the final status
347
func (s *Stream) Done() <-chan struct{} {
351
// Header returns the header metadata of the stream.
353
// On client side, it acquires the key-value pairs of header metadata once it is
354
// available. It blocks until i) the metadata is ready or ii) there is no header
355
// metadata or iii) the stream is canceled/expired.
357
// On server side, it returns the out header after t.WriteHeader is called. It
358
// does not block and must not be called until after WriteHeader.
359
func (s *Stream) Header() (metadata.MD, error) {
360
if s.headerChan == nil {
361
// On server side, return the header in stream. It will be the out
362
// header after t.WriteHeader is called.
363
return s.header.Copy(), nil
367
return nil, s.status.Err()
369
return s.header.Copy(), nil
372
// TrailersOnly blocks until a header or trailers-only frame is received and
373
// then returns true if the stream was trailers-only. If the stream ends
374
// before headers are received, returns true, nil. Client-side only.
375
func (s *Stream) TrailersOnly() bool {
380
// Trailer returns the cached trailer metedata. Note that if it is not called
381
// after the entire stream is done, it could return an empty MD. Client
383
// It can be safely read only after stream has ended that is either read
384
// or write have returned io.EOF.
385
func (s *Stream) Trailer() metadata.MD {
386
c := s.trailer.Copy()
390
// ContentSubtype returns the content-subtype for a request. For example, a
391
// content-subtype of "proto" will result in a content-type of
392
// "application/grpc+proto". This will always be lowercase. See
393
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
395
func (s *Stream) ContentSubtype() string {
396
return s.contentSubtype
399
// Context returns the context of the stream.
400
func (s *Stream) Context() context.Context {
404
// Method returns the method for the stream.
405
func (s *Stream) Method() string {
409
// Status returns the status received from the server.
410
// Status can be read safely only after the stream has ended,
411
// that is, after Done() is closed.
412
func (s *Stream) Status() *status.Status {
416
// SetHeader sets the header metadata. This can be called multiple times.
418
// This should not be called in parallel to other data writes.
419
func (s *Stream) SetHeader(md metadata.MD) error {
423
if s.isHeaderSent() || s.getState() == streamDone {
424
return ErrIllegalHeaderWrite
427
s.header = metadata.Join(s.header, md)
432
// SendHeader sends the given header metadata. The given metadata is
433
// combined with any metadata set by previous calls to SetHeader and
434
// then written to the transport stream.
435
func (s *Stream) SendHeader(md metadata.MD) error {
436
return s.st.WriteHeader(s, md)
439
// SetTrailer sets the trailer metadata which will be sent with the RPC status
440
// by the server. This can be called multiple times. Server side only.
441
// This should not be called parallel to other data writes.
442
func (s *Stream) SetTrailer(md metadata.MD) error {
446
if s.getState() == streamDone {
447
return ErrIllegalHeaderWrite
450
s.trailer = metadata.Join(s.trailer, md)
455
func (s *Stream) write(m recvMsg) {
459
// Read reads all p bytes from the wire for this stream.
460
func (s *Stream) Read(p []byte) (n int, err error) {
461
// Don't request a read if there was an error earlier
462
if er := s.trReader.(*transportReader).er; er != nil {
465
s.requestRead(len(p))
466
return io.ReadFull(s.trReader, p)
469
// tranportReader reads all the data available for this Stream from the transport and
470
// passes them into the decoder, which converts them into a gRPC message stream.
471
// The error is io.EOF when the stream is done or another non-nil error if
473
type transportReader struct {
475
// The handler to control the window update procedure for both this
476
// particular stream and the associated transport.
477
windowHandler func(int)
481
func (t *transportReader) Read(p []byte) (n int, err error) {
482
n, err = t.reader.Read(p)
491
// BytesReceived indicates whether any bytes have been received on this stream.
492
func (s *Stream) BytesReceived() bool {
493
return atomic.LoadUint32(&s.bytesReceived) == 1
496
// Unprocessed indicates whether the server did not process this stream --
497
// i.e. it sent a refused stream or GOAWAY including this stream ID.
498
func (s *Stream) Unprocessed() bool {
499
return atomic.LoadUint32(&s.unprocessed) == 1
502
// GoString is implemented by Stream so context.String() won't
503
// race when printing %#v.
504
func (s *Stream) GoString() string {
505
return fmt.Sprintf("<stream: %p, %v>", s, s.method)
509
type transportState int
512
reachable transportState = iota
517
// ServerConfig consists of all the configurations to establish a server transport.
518
type ServerConfig struct {
520
AuthInfo credentials.AuthInfo
521
InTapHandle tap.ServerInHandle
522
StatsHandler stats.Handler
523
KeepaliveParams keepalive.ServerParameters
524
KeepalivePolicy keepalive.EnforcementPolicy
525
InitialWindowSize int32
526
InitialConnWindowSize int32
529
ChannelzParentID int64
530
MaxHeaderListSize *uint32
531
HeaderTableSize *uint32
534
// NewServerTransport creates a ServerTransport with conn or non-nil error
536
func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (ServerTransport, error) {
537
return newHTTP2Server(conn, config)
540
// ConnectOptions covers all relevant options for communicating with the server.
541
type ConnectOptions struct {
542
// UserAgent is the application user agent.
544
// Dialer specifies how to dial a network address.
545
Dialer func(context.Context, string) (net.Conn, error)
546
// FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors.
547
FailOnNonTempDialError bool
548
// PerRPCCredentials stores the PerRPCCredentials required to issue RPCs.
549
PerRPCCredentials []credentials.PerRPCCredentials
550
// TransportCredentials stores the Authenticator required to setup a client
551
// connection. Only one of TransportCredentials and CredsBundle is non-nil.
552
TransportCredentials credentials.TransportCredentials
553
// CredsBundle is the credentials bundle to be used. Only one of
554
// TransportCredentials and CredsBundle is non-nil.
555
CredsBundle credentials.Bundle
556
// KeepaliveParams stores the keepalive parameters.
557
KeepaliveParams keepalive.ClientParameters
558
// StatsHandler stores the handler for stats.
559
StatsHandler stats.Handler
560
// InitialWindowSize sets the initial window size for a stream.
561
InitialWindowSize int32
562
// InitialConnWindowSize sets the initial window size for a connection.
563
InitialConnWindowSize int32
564
// WriteBufferSize sets the size of write buffer which in turn determines how much data can be batched before it's written on the wire.
566
// ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall.
568
// ChannelzParentID sets the addrConn id which initiate the creation of this client transport.
569
ChannelzParentID int64
570
// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
571
MaxHeaderListSize *uint32
572
// UseProxy specifies if a proxy should be used.
576
// NewClientTransport establishes the transport with the required ConnectOptions
577
// and returns it to the caller.
578
func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) {
579
return newHTTP2Client(connectCtx, ctx, addr, opts, onPrefaceReceipt, onGoAway, onClose)
582
// Options provides additional hints and information for message
585
// Last indicates whether this write is the last piece for
590
// CallHdr carries the information of a particular RPC.
592
// Host specifies the peer's host.
595
// Method specifies the operation to perform.
598
// SendCompress specifies the compression algorithm applied on
602
// Creds specifies credentials.PerRPCCredentials for a call.
603
Creds credentials.PerRPCCredentials
605
// ContentSubtype specifies the content-subtype for a request. For example, a
606
// content-subtype of "proto" will result in a content-type of
607
// "application/grpc+proto". The value of ContentSubtype must be all
608
// lowercase, otherwise the behavior is undefined. See
609
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
611
ContentSubtype string
613
PreviousAttempts int // value of grpc-previous-rpc-attempts header to set
616
// ClientTransport is the common interface for all gRPC client-side transport
618
type ClientTransport interface {
619
// Close tears down this transport. Once it returns, the transport
620
// should not be accessed any more. The caller must make sure this
621
// is called only once.
624
// GracefulClose starts to tear down the transport: the transport will stop
625
// accepting new RPCs and NewStream will return error. Once all streams are
626
// finished, the transport will close.
628
// It does not block.
631
// Write sends the data for the given stream. A nil stream indicates
632
// the write is to be performed on the transport as a whole.
633
Write(s *Stream, hdr []byte, data []byte, opts *Options) error
635
// NewStream creates a Stream for an RPC.
636
NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error)
638
// CloseStream clears the footprint of a stream when the stream is
639
// not needed any more. The err indicates the error incurred when
640
// CloseStream is called. Must be called when a stream is finished
641
// unless the associated transport is closing.
642
CloseStream(stream *Stream, err error)
644
// Error returns a channel that is closed when some I/O error
645
// happens. Typically the caller should have a goroutine to monitor
646
// this in order to take action (e.g., close the current transport
647
// and create a new one) in error case. It should not return nil
648
// once the transport is initiated.
649
Error() <-chan struct{}
651
// GoAway returns a channel that is closed when ClientTransport
652
// receives the draining signal from the server (e.g., GOAWAY frame in
654
GoAway() <-chan struct{}
656
// GetGoAwayReason returns the reason why GoAway frame was received.
657
GetGoAwayReason() GoAwayReason
659
// RemoteAddr returns the remote network address.
660
RemoteAddr() net.Addr
662
// IncrMsgSent increments the number of message sent through this transport.
665
// IncrMsgRecv increments the number of message received through this transport.
669
// ServerTransport is the common interface for all gRPC server-side transport
672
// Methods may be called concurrently from multiple goroutines, but
673
// Write methods for a given Stream will be called serially.
674
type ServerTransport interface {
675
// HandleStreams receives incoming streams using the given handler.
676
HandleStreams(func(*Stream), func(context.Context, string) context.Context)
678
// WriteHeader sends the header metadata for the given stream.
679
// WriteHeader may not be called on all streams.
680
WriteHeader(s *Stream, md metadata.MD) error
682
// Write sends the data for the given stream.
683
// Write may not be called on all streams.
684
Write(s *Stream, hdr []byte, data []byte, opts *Options) error
686
// WriteStatus sends the status of a stream to the client. WriteStatus is
687
// the final call made on a stream and always occurs.
688
WriteStatus(s *Stream, st *status.Status) error
690
// Close tears down the transport. Once it is called, the transport
691
// should not be accessed any more. All the pending streams and their
692
// handlers will be terminated asynchronously.
695
// RemoteAddr returns the remote network address.
696
RemoteAddr() net.Addr
698
// Drain notifies the client this ServerTransport stops accepting new RPCs.
701
// IncrMsgSent increments the number of message sent through this transport.
704
// IncrMsgRecv increments the number of message received through this transport.
708
// connectionErrorf creates an ConnectionError with the specified error description.
709
func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
710
return ConnectionError{
711
Desc: fmt.Sprintf(format, a...),
717
// ConnectionError is an error that results in the termination of the
718
// entire connection and the retry of all the active streams.
719
type ConnectionError struct {
725
func (e ConnectionError) Error() string {
726
return fmt.Sprintf("connection error: desc = %q", e.Desc)
729
// Temporary indicates if this connection error is temporary or fatal.
730
func (e ConnectionError) Temporary() bool {
734
// Origin returns the original error of this connection error.
735
func (e ConnectionError) Origin() error {
736
// Never return nil error here.
737
// If the original error is nil, return itself.
745
// ErrConnClosing indicates that the transport is closing.
746
ErrConnClosing = connectionErrorf(true, nil, "transport is closing")
747
// errStreamDrain indicates that the stream is rejected because the
748
// connection is draining. This could be caused by goaway or balancer
749
// removing the address.
750
errStreamDrain = status.Error(codes.Unavailable, "the connection is draining")
751
// errStreamDone is returned from write at the client side to indiacte application
752
// layer of an error.
753
errStreamDone = errors.New("the stream is done")
754
// StatusGoAway indicates that the server sent a GOAWAY that included this
755
// stream's ID in unprocessed RPCs.
756
statusGoAway = status.New(codes.Unavailable, "the stream is rejected because server is draining the connection")
759
// GoAwayReason contains the reason for the GoAway frame received.
760
type GoAwayReason uint8
763
// GoAwayInvalid indicates that no GoAway frame is received.
764
GoAwayInvalid GoAwayReason = 0
765
// GoAwayNoReason is the default value when GoAway frame is received.
766
GoAwayNoReason GoAwayReason = 1
767
// GoAwayTooManyPings indicates that a GoAway frame with
768
// ErrCodeEnhanceYourCalm was received and that the debug data said
770
GoAwayTooManyPings GoAwayReason = 2
773
// channelzData is used to store channelz related data for http2Client and http2Server.
774
// These fields cannot be embedded in the original structs (e.g. http2Client), since to do atomic
775
// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment.
776
// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment.
777
type channelzData struct {
779
// The number of streams that have started, including already finished ones.
781
// Client side: The number of streams that have ended successfully by receiving
782
// EoS bit set frame from server.
783
// Server side: The number of streams that have ended successfully by sending
784
// frame with EoS bit set.
785
streamsSucceeded int64
787
// lastStreamCreatedTime stores the timestamp that the last stream gets created. It is of int64 type
788
// instead of time.Time since it's more costly to atomically update time.Time variable than int64
789
// variable. The same goes for lastMsgSentTime and lastMsgRecvTime.
790
lastStreamCreatedTime int64
793
lastMsgSentTime int64
794
lastMsgRecvTime int64
797
// ContextErr converts the error from context package into a status error.
798
func ContextErr(err error) error {
800
case context.DeadlineExceeded:
801
return status.Error(codes.DeadlineExceeded, err.Error())
802
case context.Canceled:
803
return status.Error(codes.Canceled, err.Error())
805
return status.Errorf(codes.Internal, "Unexpected error from context packet: %v", err)