grpc-java icon indicating copy to clipboard operation
grpc-java copied to clipboard

`UdsChannelBuilder` does not work with WiFi Proxy on Android

Open Rawa opened this issue 10 months ago • 2 comments

UdsChannelBuilder does not work with WiFi Proxy on Android.

What version of gRPC-Java are you using?

1.70.0

What is your environment?

Android

What did you expect to see?

gRPC connection to work

What did you see instead?

TRANSIENT_FAILURE

[{0}] Failed to resolve name. status={1}
[{0}] Failed to resolve name. status={1}
[{0}] Failed to resolve name. status={1}
[{0}] Failed to resolve name. status={1}
[{0}] Failed to resolve name. status={1}
[{0}] Failed to resolve name. status={1}
[{0}] Failed to resolve name. status={1}

Steps to reproduce the bug

Setup UdsChannelBuilder and connect to a server. Connect to a WiFi on Android On the WiFi you are connected press the pen symbol to add a proxy Add a dummy proxy

The UdsChannelBuilder will be unable to connect and ends up in TRANSIENT_FAILURE state.


I've managed to find a workaround by setting proxyDetector to be null:

    private val channel =
        UdsChannelBuilder.forPath(
                rpcSocketFile.absolutePath,
                LocalSocketAddress.Namespace.FILESYSTEM,
            )
            .proxyDetector { null }
            .build()

Adding a log to the proxy detector I can see that a lookup happens:

Proxy detector invoked for: 127.0.0.1/<unresolved>:80

I believe the bug goes as follows:

Under the hood the UdsChannelBuilder uses a ManagedChannelImpl, however it with a bit of a hack uses 127.0.0.1, see here https://github.com/grpc/grpc-java/blob/57124d6b29d180de2ab7f21baeb4a2246e490c1a/android/src/main/java/io/grpc/android/UdsChannelBuilder.java#L79

By default if no ProxyDetector is set but if none is set a default is applied in ManagedChannelImpl here https://github.com/grpc/grpc-java/blob/57124d6b29d180de2ab7f21baeb4a2246e490c1a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java#L579

So default proxy detector will then yield an error when trying to lookup 127.0.0.1, maybe because internet didn't work through the proxy? My guess is that this is then emitted as an error and thus it enters here https://github.com/grpc/grpc-java/blob/57124d6b29d180de2ab7f21baeb4a2246e490c1a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java#L1836 where it logs the error and also puts the channel in TransientFailure.

Rawa avatar Feb 24 '25 14:02 Rawa

I'm not sure about the best way to address this, it is a bit weird that the entire stack depends on IP, especially for UDS. So that is a bit hard to change, I guess one could provide an empty proxyDetector by default like I did in my workaround above.

Rawa avatar Feb 24 '25 14:02 Rawa

A UDS name resolver wouldn't check the proxySelector, so disabling the proxy selector (setting a noop) sounds fine. It is annoying we don't know what error actually happened, though.

I guess one could provide an empty proxyDetector by default like I did in my workaround above

Contribution is welcome if you are so inclined.

kannanjgithub avatar Feb 25 '25 10:02 kannanjgithub

If WiFi Proxy is configured and pointing to a domain name, and yet the network is completely busted, then I can see ProxySelector unconditionally saying to proxy, then ProxyDetectorImpl resolving the proxy's address. But if the network is busted, then that fails. Maybe that's not what's being experienced, but it at least looks possible and would explain why a hard-coded IP address could still fail. And that behavior doesn't seem wrong in general, only wrong in this case we were going to throw away the result.

We actually have enough plumbing now we can make a UDS name resolver, but disabling the proxy detector is probably a fair workaround.

ejona86 avatar Oct 01 '25 16:10 ejona86