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

SOCKS proxy not working on Android platform #2315

Closed
mariotaku opened this issue Feb 4, 2016 · 3 comments
Closed

SOCKS proxy not working on Android platform #2315

mariotaku opened this issue Feb 4, 2016 · 3 comments
Labels
bug Bug in existing code

Comments

@mariotaku
Copy link

SOCKS proxy is completely broken on Android. When I set up SOCKS proxy in my app, all requests failed, when I wrote an instrumentation test, I found even create a default okhttp instance with a SOCKS proxy, it fails.

Here's the stack trace:

java.net.UnknownHostException: Host is unresolved: www.google.com
at java.net.Socket.connect(Socket.java:867)
at okhttp3.internal.Platform$Android.connectSocket(Platform.java:200)
at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:137)
at okhttp3.internal.io.RealConnection.connect(RealConnection.java:108)
at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:127)
at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:289)
at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
at okhttp3.RealCall.getResponse(RealCall.java:240)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
at okhttp3.RealCall.execute(RealCall.java:57)
at org.mariotaku.twidere.test.okhttp3.OkHttpClientTest.testSocksFunctionality(OkHttpClientTest.java:27)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:240)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)

Sample code:

import org.junit.Test;

import java.net.InetSocketAddress;
import java.net.Proxy;

import okhttp3.OkHttpClient;
import okhttp3.Request;

import static org.junit.Assert.assertTrue;

/**
 * Created by mariotaku on 16/2/5.
 */
public class OkHttpClientTest {

    @Test
    public void testSocksFunctionality() throws Exception {
        final Proxy proxy = new Proxy(Proxy.Type.SOCKS, InetSocketAddress.createUnresolved("127.0.0.1", 1080));
        final OkHttpClient client = new OkHttpClient.Builder()
                .proxy(proxy)
                .build();
        final Request request = new Request.Builder()
                .url("https://www.google.com/")
                .build();
        assertTrue(client.newCall(request).execute().isSuccessful());
    }

}
@mariotaku
Copy link
Author

Seems it's a bug inside Android Socket implementation.

SOCKS working fine on Oracle JRE and OpenJDK JRE, and I looked into their code:
Socket.connect(SocketAddress endpoint, int timeout)

            if (epoint.isUnresolved())
                impl.connect(addr.getHostName(), port);
            else
                impl.connect(addr, port);

That's what I found in Android framework:

        InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr;
        InetAddress addr;
        if ((addr = inetAddr.getAddress()) == null) {
            throw new UnknownHostException("Host is unresolved: " + inetAddr.getHostName());
        }
        int port = inetAddr.getPort();

        checkDestination(addr, port);
        synchronized (connectLock) {
            try {
                if (!isBound()) {
                    // socket already created at this point by earlier call or
                    // checkOpenAndCreate this caused us to lose socket
                    // options on create
                    // impl.create(true);
                    if (!usingSocks()) {
                        impl.bind(Inet6Address.ANY, 0);
                    }
                    isBound = true;
                }
                impl.connect(remoteAddr, timeout);
                isConnected = true;
                cacheLocalAddress();
            } catch (IOException e) {
                impl.close();
                throw e;
            }
        }

Android only accept resolved InetSocketAddress.

@swankjesse swankjesse added the bug Bug in existing code label Feb 5, 2016
mariotaku added a commit to TwidereProject/Twidere-Android that referenced this issue Feb 5, 2016
vanita5 pushed a commit to vanita5/twittnuker that referenced this issue Feb 6, 2016
@swankjesse
Copy link
Member

Could you report this issue upstream to AOSP? I’m not particularly eager to implement a SOCKS proxy inside of OkHttp. You might need to implement your own SocketFactory that implements SOCKS.

@swankjesse
Copy link
Member

No action for us to take on this.

FHandrick pushed a commit to project-draco-hr/Twidere-Android that referenced this issue Oct 4, 2016
bemasc pushed a commit to bemasc/okhttp that referenced this issue Dec 3, 2018
This is currently nonfunctional due to an interaction
between InetAddress.createUnresolved and the SOCKS 4 protocol.

Fixes square#2315
bemasc pushed a commit to bemasc/okhttp that referenced this issue Dec 3, 2018
This is currently nonfunctional due to an interaction
between InetAddress.createUnresolved and the SOCKS 4 protocol.

Fixes square#2315
bemasc pushed a commit to bemasc/okhttp that referenced this issue Dec 4, 2018
Currently, setting a SOCKS proxy in OkHttpClient.Builder
silently overrides any custom DNS setting.  This changes
behavior for users who are currently using both settings
in a single Builder, but any such usage is likely already
buggy because the custom DNS setting is being ignored.

This also fixes square#2315 (SOCKS 4 support) if users "opt in"
by adding a custom DNS setting in their Builder.
bemasc pushed a commit to bemasc/okhttp that referenced this issue Feb 28, 2019
Currently, setting a SOCKS proxy in OkHttpClient.Builder
silently overrides any custom DNS setting.  This changes
behavior for users who are currently using both settings
in a single Builder, but any such usage is likely already
buggy because the custom DNS setting is being ignored.

This also fixes square#2315 (SOCKS 4 support) if users "opt in"
by adding a custom DNS setting in their Builder.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug in existing code
Projects
None yet
2 participants