Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cronvoy: Negotiated Protocol #1546

Open
carloseltuerto opened this issue Jun 24, 2021 · 13 comments
Open

Cronvoy: Negotiated Protocol #1546

carloseltuerto opened this issue Jun 24, 2021 · 13 comments
Assignees
Labels

Comments

@carloseltuerto
Copy link
Contributor

As part of the Cronet API, the Cornet Engine exposes the "Negotiated Protocol".

/**
 * Returns the protocol (for example 'quic/1+spdy/3') negotiated with the server.
 * Returns an empty string if no protocol was negotiated, the protocol is
 * not known, or when using plain HTTP or HTTPS.
 */
public String getNegotiatedProtocol()

This somehow will need to be resurfaced by the Envoy Mobile Engine. I guess that adding a x-envoy-negotiated-protocol response header would suffice.

@alyssawilk
Copy link
Contributor

yeah, I think this needs to go in StreamInfo somewhere (I can take that) then we have to expose up to mobile. @junr03 / @goaway is there a generic way for mobile to get access to streaminfo fields or a example code you can point me to where we do that now?

@alyssawilk
Copy link
Contributor

Question for @carloseltuerto / @DavidSchinazi / @RyanTheOptimist if no protocol is negotiated (ALPN not attempted) is this still filled in with the protocol used?
AFIK Cronvoy is still hard-coded to use HTTP/2 by default so isn't actually negotiating. I should fix that, though that'll need more coordination with the lyfties becasue [implementation details]

@RyanTheOptimist
Copy link
Contributor

RyanTheOptimist commented Jun 24, 2021

Based on my reading of the code, if ALPN is not use then the negotiated protocol will be unknown.

  // Returns the protocol negotiated via ALPN for this socket, or
  // kProtoUnknown will be returned if ALPN is not applicable.
  virtual NextProto GetNegotiatedProtocol() const = 0;

https://source.chromium.org/chromium/chromium/src/+/main:net/socket/stream_socket.h;l=137?q=getNegotiatedProtocol&ss=chromium

https://source.chromium.org/chromium/chromium/src/+/main:net/socket/ssl_client_socket_impl.cc;l=560;drc=d53e1d68f1d6a20877b5e845cd88dd393bf7dd75;bpv=1;bpt=1

@carloseltuerto
Copy link
Contributor Author

The description of the getNegotiatedProtocol() states that the returned String is empty when using plain https or http. I browsed chromium for tests, and here are the strings I got (maybe some are bogus):

"h2"
"h3"
"http/2+quic"
"quic/1+spdy/3"

https://source.chromium.org/search?q=getNegotiatedProtocol%20f:test.java&sq=&ss=chromium

I guess more efforts are needed to figure out the exhaustive list of possible values. Maybe someone with Cronet experience would know where to look.

@RyanTheOptimist
Copy link
Contributor

RyanTheOptimist commented Jun 24, 2021

Yes those sound like correct ALPN strings. I would not think that you would need an exhaustive list of values. Instead, I would hope that you could ask envoy for the ALPN string and it would give the correct value?

@alyssawilk
Copy link
Contributor

Maybe - I'm not 100% sure if Envoy would return http if it fails over to HTTP/1.1, or if it'd return an empty string. I'll make sure to test and loop back if the default is different than Cronets.

@carloseltuerto
Copy link
Contributor Author

If Envoy Mobile returns "HTTP/1.1", Cronvoy could convert it to an empty String. I guess where that hacking occurs can be discussed, if this is happening.

@DavidSchinazi
Copy link

The official list of ALPN protocol IDs is here (note that you want to check the Identification Sequence column, not the Protocol column). If Envoy is hardcoded to use a given protocol instead of negotiating it via ALPN, I'd suggest having Envoy return the ALPN protocol ID for the configured protocol (such as h2) instead of the empty string. What do you think @alyssawilk?

Some additional notes:

  • http and https are not valid ALPN protocol IDs, they're schemes that go over ALPN protocols
  • any ALPN protocol ID that contains quic was a Google-specific invention during the early days of QUIC, and those old QUIC versions will not be supported in Cronet nor Envoy for long so we can ignore them here
  • when using a non-secure protocol (not TLS and not QUIC), then there is no ALPN exchanged, so http requests generally don't have one.

@alyssawilk
Copy link
Contributor

I'd be inclined to look at the code. If when hard-coded to H2 Envoy does ALPN and fails if it doesn't negotiate h2, I'd return H2. In the unlikely event it doesn't negotiate when not configured I'd rather reflect reality.

alyssawilk added a commit to envoyproxy/envoy that referenced this issue Nov 10, 2021
Part of envoyproxy/envoy-mobile#1546

Risk Level: Low
Testing: new integration test
Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
@alyssawilk
Copy link
Contributor

@goaway WDYT about making an explicit accessor for this vs sticking alpn in stream intel and doing string copies on every up call?

@alyssawilk
Copy link
Contributor

-> charles for header - > cronet API (though the header will be blank if we're not using the ALPN cluster or doing HTTP/3)

@colibie
Copy link
Contributor

colibie commented Aug 25, 2022

@carloseltuerto could you please close this issue. It's implemented via #2164

@carloseltuerto
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants