1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-25 21:42:07 +01:00

Rework support for Proxy connections

in order to improve support for Tor connections.

This makes it possible to establish a connection to an .onion domain by
manually setting host and port in the ConnectionConfiguration and
configuring a Socks5Proxy pointing to a Tor node.

Fixes SMACK-720.
This commit is contained in:
Florian Schmaus 2016-05-03 09:59:20 +02:00
parent 3251fe89e2
commit 4c63cfafd7
5 changed files with 51 additions and 44 deletions

View file

@ -21,7 +21,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
@ -45,12 +44,12 @@ class HTTPProxySocketConnection implements ProxySocketConnection {
} }
@Override @Override
public void connect(Socket socket, InetAddress inetAddress, int port, int timeout) public void connect(Socket socket, String host, int port, int timeout)
throws IOException { throws IOException {
String proxyhost = proxy.getProxyAddress(); String proxyhost = proxy.getProxyAddress();
int proxyPort = proxy.getProxyPort(); int proxyPort = proxy.getProxyPort();
socket.connect(new InetSocketAddress(proxyhost, proxyPort)); socket.connect(new InetSocketAddress(proxyhost, proxyPort));
String hostport = "CONNECT " + inetAddress.getCanonicalHostName() + ":" + port; String hostport = "CONNECT " + host + ":" + port;
String proxyLine; String proxyLine;
String username = proxy.getProxyUsername(); String username = proxy.getProxyUsername();
if (username == null) if (username == null)

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2015 Florian Schmaus. * Copyright 2015-2016 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,12 +17,11 @@
package org.jivesoftware.smack.proxy; package org.jivesoftware.smack.proxy;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
public interface ProxySocketConnection { public interface ProxySocketConnection {
public void connect(Socket socket, InetAddress inetAddress, int port, int timeout) public void connect(Socket socket, String host, int port, int timeout)
throws IOException; throws IOException;
} }

View file

@ -37,7 +37,7 @@ public class Socks4ProxySocketConnection implements ProxySocketConnection {
} }
@Override @Override
public void connect(Socket socket, InetAddress inetAddress, int port, int timeout) public void connect(Socket socket, String host, int port, int timeout)
throws IOException { throws IOException {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
@ -80,6 +80,7 @@ public class Socks4ProxySocketConnection implements ProxySocketConnection {
buf[index++]=(byte)(port>>>8); buf[index++]=(byte)(port>>>8);
buf[index++]=(byte)(port&0xff); buf[index++]=(byte)(port&0xff);
InetAddress inetAddress = InetAddress.getByName(proxy_host);
byte[] byteAddress = inetAddress.getAddress(); byte[] byteAddress = inetAddress.getAddress();
for (int i = 0; i < byteAddress.length; i++) for (int i = 0; i < byteAddress.length; i++)
{ {

View file

@ -19,7 +19,6 @@ package org.jivesoftware.smack.proxy;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
@ -37,7 +36,7 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
} }
@Override @Override
public void connect(Socket socket, InetAddress inetAddress, int port, int timeout) public void connect(Socket socket, String host, int port, int timeout)
throws IOException { throws IOException {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
@ -211,7 +210,7 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
buf[index++]=1; // CONNECT buf[index++]=1; // CONNECT
buf[index++]=0; buf[index++]=0;
byte[] hostb= inetAddress.getCanonicalHostName().getBytes(); byte[] hostb= host.getBytes();
int len=hostb.length; int len=hostb.length;
buf[index++]=3; // DOMAINNAME buf[index++]=3; // DOMAINNAME
buf[index++]=(byte)(len); buf[index++]=(byte)(len);

View file

@ -554,48 +554,57 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
Iterator<InetAddress> inetAddresses = null; Iterator<InetAddress> inetAddresses = null;
String host = hostAddress.getFQDN(); String host = hostAddress.getFQDN();
int port = hostAddress.getPort(); int port = hostAddress.getPort();
try { if (proxyInfo == null) {
inetAddresses = Arrays.asList(InetAddress.getAllByName(host)).iterator();
if (!inetAddresses.hasNext()) {
// This should not happen
LOGGER.warning("InetAddress.getAllByName() returned empty result array.");
throw new UnknownHostException(host);
}
}
catch (UnknownHostException e) {
hostAddress.setException(e);
// TODO: Change to emptyIterator() once Smack's minimum Android SDK level is >= 19.
List<InetAddress> emptyInetAddresses = Collections.emptyList();
inetAddresses = emptyInetAddresses.iterator();
continue;
}
innerloop: while (inetAddresses.hasNext()) {
final InetAddress inetAddress = inetAddresses.next();
final String inetAddressAndPort = inetAddress + " at port " + port;
LOGGER.finer("Trying to establish TCP connection to " + inetAddressAndPort);
try { try {
if (proxyInfo == null) { inetAddresses = Arrays.asList(InetAddress.getAllByName(host)).iterator();
socket.connect(new InetSocketAddress(inetAddress, port), timeout); if (!inetAddresses.hasNext()) {
} // This should not happen
else { LOGGER.warning("InetAddress.getAllByName() returned empty result array.");
proxyInfo.getProxySocketConnection().connect(socket, inetAddress, port, timeout); throw new UnknownHostException(host);
}
} catch (Exception e) {
hostAddress.setException(inetAddress, e);
if (inetAddresses.hasNext()) {
continue innerloop;
}
else {
break innerloop;
} }
} catch (UnknownHostException e) {
hostAddress.setException(e);
// TODO: Change to emptyIterator() once Smack's minimum Android SDK level is >= 19.
List<InetAddress> emptyInetAddresses = Collections.emptyList();
inetAddresses = emptyInetAddresses.iterator();
continue;
} }
LOGGER.finer("Established TCP connection to " + inetAddressAndPort); innerloop: while (inetAddresses.hasNext()) {
final InetAddress inetAddress = inetAddresses.next();
final String inetAddressAndPort = inetAddress + " at port " + port;
LOGGER.finer("Trying to establish TCP connection to " + inetAddressAndPort);
try {
socket.connect(new InetSocketAddress(inetAddress, port), timeout);
} catch (Exception e) {
hostAddress.setException(inetAddress, e);
if (inetAddresses.hasNext()) {
continue innerloop;
} else {
break innerloop;
}
}
LOGGER.finer("Established TCP connection to " + inetAddressAndPort);
// We found a host to connect to, return here
this.host = host;
this.port = port;
return;
}
failedAddresses.add(hostAddress);
} else {
final String hostAndPort = host + " at port " + port;
LOGGER.finer("Trying to establish TCP connection via Proxy to " + hostAndPort);
try {
proxyInfo.getProxySocketConnection().connect(socket, host, port, timeout);
} catch (IOException e) {
hostAddress.setException(e);
continue;
}
LOGGER.finer("Established TCP connection to " + hostAndPort);
// We found a host to connect to, return here // We found a host to connect to, return here
this.host = host; this.host = host;
this.port = port; this.port = port;
return; return;
} }
failedAddresses.add(hostAddress);
} }
// There are no more host addresses to try // There are no more host addresses to try
// throw an exception and report all tried // throw an exception and report all tried