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 private static final byte[] LOCALHOST = new byte[]{127,0,0,1};
16
17 public static void createSocksConnection(Socket socket, String destination, int port) throws IOException {
18 InputStream proxyIs = socket.getInputStream();
19 OutputStream proxyOs = socket.getOutputStream();
20 proxyOs.write(new byte[]{0x05, 0x01, 0x00});
21 byte[] response = new byte[2];
22 proxyIs.read(response);
23 if (response[0] != 0x05 || response[1] != 0x00) {
24 throw new SocksConnectionException();
25 }
26 byte[] dest = destination.getBytes();
27 ByteBuffer request = ByteBuffer.allocate(7 + dest.length);
28 request.put(new byte[]{0x05, 0x01, 0x00, 0x03});
29 request.put((byte) dest.length);
30 request.put(dest);
31 request.putShort((short) port);
32 proxyOs.write(request.array());
33 response = new byte[7 + dest.length];
34 proxyIs.read(response);
35 if (response[1] != 0x00) {
36 throw new SocksConnectionException();
37 }
38 }
39
40 public static boolean contains(byte needle, byte[] haystack) {
41 for(byte hay : haystack) {
42 if (hay == needle) {
43 return true;
44 }
45 }
46 return false;
47 }
48
49 public static Socket createSocket(InetSocketAddress address, String destination, int port) throws IOException {
50 Socket socket = new Socket();
51 try {
52 socket.connect(address, Config.CONNECT_TIMEOUT * 1000);
53 } catch (IOException e) {
54 throw new SocksProxyNotFoundException();
55 }
56 createSocksConnection(socket, destination, port);
57 return socket;
58 }
59
60 public static Socket createSocketOverTor(String destination, int port) throws IOException {
61 return createSocket(new InetSocketAddress(InetAddress.getByAddress(LOCALHOST), 9050), destination, port);
62 }
63
64 static class SocksConnectionException extends IOException {
65
66 }
67
68 public static class SocksProxyNotFoundException extends IOException {
69
70 }
71}