Skip to content

grpc: add PeerInfo to client's ResponseHeaders and Trailers - #2802

Open
dfawley wants to merge 3 commits into
grpc:masterfrom
dfawley:peer
Open

grpc: add PeerInfo to client's ResponseHeaders and Trailers#2802
dfawley wants to merge 3 commits into
grpc:masterfrom
dfawley:peer

Conversation

@dfawley

@dfawley dfawley commented Aug 13, 2026

Copy link
Copy Markdown
Member

Also: return PeerInfo from Transport::connect instead of SecurityInfo (yes, I know I just changed it to produce SecurityInfo) so that the subchannel can set the full PeerInfo in Trailers when producing errors locally, since the address of the subchannel may be relevant to those errors.

FWIW I wanted to make the subchannel apply an interceptor that could always set PeerInfo in response streams (either ResponseHeaders or in Trailers-only responses), but because the field is mandatory in ResponseHeaders, the transport would need to set it to some default/empty value, which felt wrong. Anything producing a ResponseHeaders or Trailers should ensure the PeerInfo is set correctly.

cc @joshuatants as FYI - this is the change that will provide you with the ability to determine the server's address.

@dfawley dfawley added this to the grpc-next milestone Aug 13, 2026
@dfawley
dfawley requested review from arjan-bal and ejona86 August 13, 2026 20:35
@dfawley

dfawley commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

@arjan-bal - I had to merge in the cancellation changes that you recently submitted. I'm a little uncertain about the tonic behavior if we call cancel on the token after the stream has ended naturally -- i.e. the tonic recv stream returns Ok(None) or Err(status).

In these cases, IIUC tonic itself should send a RST_STREAM(NO_ERROR) as soon as the server ends the stream (via trailers or RST_STREAM) if the client was not already half-closed, or do nothing if it was, and ignore the cancellation token. Do you know if tonic is already doing all this correctly?

@ejona86 ejona86 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't have time to look at it deeply.

TonicRecvStream {
state: StreamState::AwaitingHeaders(resp_rx),
cancel_tx: Some(cancel_tx),
peer_info: Some(self.peer_info.clone()),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to clone the entire thing? I see we're cloning the entire thing for CallCredentials already. Are we going to Arc things inside Attributes instead, like the client's certificate?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attributes is a linked list with Arc'd nodes, so a clone of PeerInfo is fairly small:

  • Two Addresses, each with &'static, ByteStr (contains Bytes whose data is Arc'd), Attributes (Arc'd)
  • One SecurityInfo with &'static, SecurityLevel (3 value enum with no data), and Attributes (Arc'd)

I do want to delete the Attributes from Address, so it would be down to two Arcs: the ByteStr and SecurityInfo.

The tradeoff would be simplicity for performance. If PeerInfo needed to be mutated in the stack somewhere, it might be worse if it was Arc'd. But, I wouldn't expect that to happen, so maybe it's best in its own Arc?

I think we could change this in a hidden/backward compatible way if we wanted to convert it to hold Arc<InnerPeerInfo>. The accessors just hand out references, which could be references to the value inside the Arc, and PeerInfo is immutable.

Comment thread grpc/src/core/mod.rs
/// pair).
#[derive(Debug, Clone)]
pub struct PeerInfo {
local_address: Address,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local address is in the peer's information?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did 👀 at this as well. PeerInfo->ConnectionInfo? We call it Peer in Go and have the local address there (just FYI, not as justification; it happened that we added it later there): https://pkg.go.dev/google.golang.org/grpc/peer#Peer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants