How to let Tor service to perform the DNS resolution using Socket?

I want to use Java Socket with SOCKS proxy to connect on Tor (I am using Orbot and Tor service is running on port 9050 ).

I got the error :

I/System.out: java.net.UnknownHostException: Host is unresolved: 3g2upl4pq6kufc4m.onion

My code is as follow :

// 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);

This is legitimate, as Android will probably perform DNS resolution via DNS server specified in network configuration and the resolution of onion address will not work.

How do I specify to let Tor service to perform the DNS resolution (Tor will normally handle the hostname from the TCP packet) ?


The correct way of doing this is to use InetSocketAddress.createUnresolved(...) method but this throws an exception on Android.

As a work around we need to implement Socks ourselves like here: http://www.mit.edu/~foley/TinFoil/src/tinfoil/TorLib.java

An explanation is here: https://github.com/acomminos/OnionKit/blob/master/libnetcipher/src/info/guardianproject/onionkit/proxy/SocksProxyClientConnOperator.java

Basically:

        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

You should pass unresolved socket to Orbot library. It should be created like this:

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

By the way, if you use apache's httpClient, you can find a sample here.

链接地址: http://www.djcxy.com/p/48548.html

上一篇: 问题添加附件到CouchDB中的文档

下一篇: 如何让Tor服务使用Socket执行DNS解析?