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 }