mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +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:
parent
3251fe89e2
commit
4c63cfafd7
5 changed files with 51 additions and 44 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue