1package eu.siacs.conversations.utils;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.OutputStream;
6import java.net.InetAddress;
7import java.net.InetSocketAddress;
8import java.net.Socket;
9import java.nio.ByteBuffer;
10
11import eu.siacs.conversations.Config;
12
13public class SocksSocketFactory {
14
15 public static void createSocksConnection(Socket socket, String destination, int port) throws IOException {
16 InputStream proxyIs = socket.getInputStream();
17 OutputStream proxyOs = socket.getOutputStream();
18 proxyOs.write(new byte[]{0x05, 0x01, 0x00});
19 byte[] response = new byte[2];
20 proxyIs.read(response);
21 byte[] dest = destination.getBytes();
22 ByteBuffer request = ByteBuffer.allocate(7 + dest.length);
23 request.put(new byte[]{0x05, 0x01, 0x00, 0x03});
24 request.put((byte) dest.length);
25 request.put(dest);
26 request.putShort((short) port);
27 proxyOs.write(request.array());
28 response = new byte[7 + dest.length];
29 proxyIs.read(response);
30 if (response[1] != 0x00) {
31 throw new SocksConnectionException();
32 }
33 }
34
35 public static Socket createSocket(InetSocketAddress address, String destination, int port) throws IOException {
36 Socket socket = new Socket();
37 try {
38 socket.connect(address, Config.CONNECT_TIMEOUT * 1000);
39 } catch (IOException e) {
40 throw new SocksProxyNotFoundException();
41 }
42 createSocksConnection(socket, destination, port);
43 return socket;
44 }
45
46 public static Socket createSocketOverTor(String destination, int port) throws IOException {
47 return createSocket(new InetSocketAddress(InetAddress.getLocalHost(), 9050), destination, port);
48 }
49
50 static class SocksConnectionException extends IOException {
51
52 }
53
54 public static class SocksProxyNotFoundException extends IOException {
55
56 }
57}