简体   繁体   中英

Android grpc error: TLS ALPN negotiation failed with protocols: [grpc-exp, h2]

I'm trying to use grpc in an Android App

The important part of the code is this:

private val managedChannel: ManagedChannel = ManagedChannelBuilder
        .forTarget("misserverurl.com")
        .build()

build.gradle with version and dependencies:

minSdkVersion 19

implementation "io.grpc:grpc-okhttp:1.26.0"
implementation "io.grpc:grpc-protobuf:1.26.0"
implementation "io.grpc:grpc-stub:1.26.0"

The protos seems okay, and the app works without TLS ( .usePlaintext() )

But I'm getting this error:

java.lang.RuntimeException: TLS ALPN negotiation failed with protocols: [grpc-exp, h2]

Where it seems there is a problem with the SSL handshake .

The weird part is that the server works using BloomRCP using TLS.

I've tried with different minSdkVersions, also using different io.grpc.* lib versions and creating an empty repo with just the proto files and the basic code to run it but nothing and adding .connectionSpec() with different CipherSuite as well.

Using Wireshark I could see that the TLS version that I'm sending is 1.2 which is correct and expected (maybe it's not using HTTP2?)

Any guest? Thanks in advance!

--------------------------------------------------- Edit ---------------------------------------------------

Look into the lib I've found this method: useTransportSecurity()

/**
* Sets the negotiation type for the HTTP/2 connection to TLS (this is the default).
...
*/
@Override
public final OkHttpChannelBuilder useTransportSecurity() { ... }

We are using TLS with HTTP/2 by default, so that's not the problem...

HTTP/2 is negotiated during TLS using ALPN. The client sends what protocols it supports (in this case grpc-exp and h2, aka http/2). The server then selects what protocol, or none. If none is selected then the only options are to fall back to another protocol like HTTP/1 or to fail.

gRPC requires HTTP/2, so the server must select 'h2' via ALPN. The error is that didn't happen. Your server needs to support HTTP/2. If you are using a TLS terminator or you are using an L7 load balancer, you must configure it to support HTTP/2.

Finally it was a backend issue. Following this:https://www.getambassador.io/reference/core/tls/#alpn_protocols The alpn_protocol was set like this:

alpn_protocol = h2[, grpc-epx]

Where it should be:

alpn_protocol = h2

With that and this config in client side, it worked!

private val managedChannel: ManagedChannel = ManagedChannelBuilder
        .forTarget("misserverurl.com")
        .build()

之前用java 1.8.0_242-b08时遇到过这个问题,升级到1.8.0_265后就没有问题了

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM