2

我想使用带有 SOCKS 代理的 Java Socket 来连接 Tor(我正在使用 Orbot 并且 Tor 服务在端口 9050 上运行)。

我得到了错误:

I/System.out:java.net.UnknownHostException:主机未解析:3g2upl4pq6kufc4m.onion

我的代码如下:

// setup proxy
address = new InetSocketAddress('localhost', 9050);
proxy = new java.net.Proxy(java.net.Proxy.Type.SOCKS,address);
// setup socket
client = new Socket(proxy);
inet = new InetSocketAddress("3g2upl4pq6kufc4m.onion", 80);
// connect
client.connect(inet);

这是合法的,因为 Android 可能会通过网络配置中指定的 DNS 服务器执行 DNS 解析,而洋葱地址的解析将不起作用。

如何指定让 Tor 服务执行 DNS 解析(Tor 通常会处理来自 TCP 数据包的主机名)?

4

2 回答 2

1

这样做的正确方法是使用InetSocketAddress.createUnresolved(...)方法,但这会在 Android 上引发异常。

作为一种解决方法,我们需要像这里一样自己实现 Socks:http: //www.mit.edu/~foley/TinFoil/src/tinfoil/TorLib.java

解释在这里:https ://github.com/acomminos/OnionKit/blob/master/libnetcipher/src/info/guardianproject/onionkit/proxy/SocksProxyClientConnOperator.java

基本上:

        socket = new Socket();
        socket.setSoTimeout(READ_TIMEOUT_MILLISECONDS);
        socket.connect(new InetSocketAddress(mProxyHost, mProxyPort), CONNECT_TIMEOUT_MILLISECONDS);

        DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
        outputStream.write((byte)0x04);
        outputStream.write((byte)0x01);
        outputStream.writeShort((short)port);
        outputStream.writeInt(0x01);
        outputStream.write((byte)0x00);
        outputStream.write(host.getBytes());
        outputStream.write((byte)0x00);

        DataInputStream inputStream = new DataInputStream(socket.getInputStream());
        if (inputStream.readByte() != (byte)0x00 || inputStream.readByte() != (byte)0x5a) {
            throw new IOException("SOCKS4a connect failed");
        }
        inputStream.readShort();
        inputStream.readInt();
        //socket is ready to use
于 2017-01-18T00:37:35.153 回答
0

您应该将未解析的套接字传递给 Orbot 库。它应该像这样创建:

InetSocketAddress unresolvedRemote = InetSocketAddress.
createUnresolved(host.getHostName(), remoteAddress.getPort());

顺便说一句,如果你使用 apache 的 httpClient,你可以在这里找到一个示例。

于 2016-10-18T12:12:06.353 回答