mirror of
https://github.com/bisq-network/bisq.git
synced 2025-01-19 05:44:05 +01:00
Merged PR (https://github.com/bitsquare/bitsquare/pull/730) with some fixes and improvements. Use bitcoinj v 0.13.1.8
This commit is contained in:
parent
93c1700796
commit
e1d917f6c7
@ -93,6 +93,9 @@ public abstract class BitsquareExecutable {
|
||||
.withRequiredArg();
|
||||
parser.accepts(NetworkOptionKeys.SOCKS_5_PROXY_HTTP_ADDRESS, description("A proxy address to be used for Http requests (should be non-Tor). [host:port]", ""))
|
||||
.withRequiredArg();
|
||||
parser.accepts(NetworkOptionKeys.SOCKS5_DISCOVER_MODE, description("Specify discovery mode for Bitcoin nodes. One or more of: [ADDR, DNS, ONION, ALL]" +
|
||||
" (comma separated, they get OR'd together). Default value is ALL", "ALL"))
|
||||
.withRequiredArg();
|
||||
|
||||
parser.accepts(AppOptionKeys.USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR))
|
||||
.withRequiredArg();
|
||||
|
@ -32,15 +32,18 @@ import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ExceptionHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.network.DnsLookupTor;
|
||||
import io.bitsquare.network.NetworkOptionKeys;
|
||||
import io.bitsquare.network.Socks5MultiDiscovery;
|
||||
import io.bitsquare.network.Socks5ProxyProvider;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
import org.bitcoinj.net.discovery.SeedPeers;
|
||||
import org.bitcoinj.params.MainNetParams;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
import org.bitcoinj.params.TestNet3Params;
|
||||
@ -92,6 +95,7 @@ public class WalletService {
|
||||
private final NetworkParameters params;
|
||||
private final File walletDir;
|
||||
private final UserAgent userAgent;
|
||||
private final int socks5DiscoverMode;
|
||||
|
||||
private WalletAppKitBitSquare walletAppKit;
|
||||
private Wallet wallet;
|
||||
@ -114,7 +118,8 @@ public class WalletService {
|
||||
UserAgent userAgent,
|
||||
Preferences preferences,
|
||||
Socks5ProxyProvider socks5ProxyProvider,
|
||||
@Named(BtcOptionKeys.WALLET_DIR) File appDir) {
|
||||
@Named(BtcOptionKeys.WALLET_DIR) File appDir,
|
||||
@Named(NetworkOptionKeys.SOCKS5_DISCOVER_MODE) String socks5DiscoverModeString) {
|
||||
this.regTestHost = regTestHost;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.addressEntryList = addressEntryList;
|
||||
@ -132,6 +137,23 @@ public class WalletService {
|
||||
bloomFilterTweak = new Random().nextLong();
|
||||
storage.queueUpForSave(bloomFilterTweak, 100);
|
||||
}
|
||||
|
||||
String[] socks5DiscoverModes = StringUtils.deleteWhitespace(socks5DiscoverModeString).split(",");
|
||||
int mode = 0;
|
||||
for (int i = 0; i < socks5DiscoverModes.length; i++) {
|
||||
switch (socks5DiscoverModes[i]) {
|
||||
case "ADDR":
|
||||
mode |= Socks5MultiDiscovery.SOCKS5_DISCOVER_ADDR;
|
||||
case "DNS":
|
||||
mode |= Socks5MultiDiscovery.SOCKS5_DISCOVER_DNS;
|
||||
case "ONION":
|
||||
mode |= Socks5MultiDiscovery.SOCKS5_DISCOVER_ONION;
|
||||
case "ALL":
|
||||
default:
|
||||
mode |= Socks5MultiDiscovery.SOCKS5_DISCOVER_ALL;
|
||||
}
|
||||
}
|
||||
socks5DiscoverMode = mode;
|
||||
}
|
||||
|
||||
|
||||
@ -266,9 +288,7 @@ public class WalletService {
|
||||
// Pass custom seed nodes if set in options
|
||||
if (!btcNodes.isEmpty()) {
|
||||
|
||||
// TODO: this parsing should be more robust,
|
||||
// give validation error if needed.
|
||||
String[] nodes = btcNodes.replace(", ", ",").split(",");
|
||||
String[] nodes = StringUtils.deleteWhitespace(btcNodes).split(",");
|
||||
List<PeerAddress> peerAddressList = new ArrayList<>();
|
||||
for (String node : nodes) {
|
||||
String[] parts = node.split(":");
|
||||
@ -279,21 +299,25 @@ public class WalletService {
|
||||
if (parts.length == 2) {
|
||||
// note: this will cause a DNS request if hostname used.
|
||||
// note: DNS requests are routed over socks5 proxy, if used.
|
||||
// fixme: .onion hostnames will fail! see comments in SeedPeersSocks5Dns
|
||||
// note: .onion hostnames will be unresolved.
|
||||
InetSocketAddress addr;
|
||||
if (socks5Proxy != null) {
|
||||
InetSocketAddress unresolved = InetSocketAddress.createUnresolved(parts[0], Integer.parseInt(parts[1]));
|
||||
// proxy remote DNS request happens here.
|
||||
addr = SeedPeersSocks5Dns.lookup(socks5Proxy, unresolved);
|
||||
try {
|
||||
// proxy remote DNS request happens here. blocking.
|
||||
addr = new InetSocketAddress(DnsLookupTor.lookup(socks5Proxy, parts[0]), Integer.parseInt(parts[1]));
|
||||
} catch (Exception e) {
|
||||
log.warn("Dns lookup failed for host: {}", parts[0]);
|
||||
addr = null;
|
||||
}
|
||||
} else {
|
||||
// DNS request happens here. if it fails, addr.isUnresolved() == true.
|
||||
addr = new InetSocketAddress(parts[0], Integer.parseInt(parts[1]));
|
||||
}
|
||||
// note: isUnresolved check should be removed once we fix PeerAddress
|
||||
if (addr != null && !addr.isUnresolved())
|
||||
if (addr != null && !addr.isUnresolved()) {
|
||||
peerAddressList.add(new PeerAddress(addr.getAddress(), addr.getPort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (peerAddressList.size() > 0) {
|
||||
PeerAddress peerAddressListFixed[] = new PeerAddress[peerAddressList.size()];
|
||||
log.debug("btcNodes parsed: " + Arrays.toString(peerAddressListFixed));
|
||||
@ -343,9 +367,8 @@ public class WalletService {
|
||||
// could become outdated, so it is important that the user be able to
|
||||
// disable it, but should be made aware of the reduced privacy.
|
||||
if (socks5Proxy != null && !usePeerNodes) {
|
||||
// SeedPeersSocks5Dns should replace SeedPeers once working reliably.
|
||||
// SeedPeers uses hard coded stable addresses (from MainNetParams). It should be updated from time to time.
|
||||
walletAppKit.setDiscovery(new SeedPeers(params));
|
||||
walletAppKit.setDiscovery(new Socks5MultiDiscovery(socks5Proxy, params, socks5DiscoverMode));
|
||||
}
|
||||
|
||||
walletAppKit.setDownloadListener(downloadListener)
|
||||
@ -1131,9 +1154,9 @@ public class WalletService {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Inner classes
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Inner classes
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class DownloadListener extends DownloadProgressTracker {
|
||||
private final DoubleProperty percentage = new SimpleDoubleProperty(-1);
|
||||
|
@ -18,21 +18,19 @@
|
||||
package io.bitsquare.network;
|
||||
|
||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Performs DNS lookup over Socks5 proxy that implements the RESOLVE extension.
|
||||
* At this time, Tor is only known Socks5 proxy that supports it.
|
||||
*
|
||||
* <p>
|
||||
* Adapted from https://github.com/btcsuite/btcd/blob/master/connmgr/tor.go
|
||||
*/
|
||||
public class DnsLookupTor {
|
||||
@ -41,103 +39,93 @@ public class DnsLookupTor {
|
||||
|
||||
private static Map<Byte, String> createMap() {
|
||||
HashMap<Byte, String> map = new HashMap<Byte, String>();
|
||||
map.put(Byte.valueOf(b('\u0000')), "tor succeeded");
|
||||
map.put(Byte.valueOf(b('\u0001')), "tor general error");
|
||||
map.put(Byte.valueOf(b('\u0002')), "tor not allowed");
|
||||
map.put(Byte.valueOf(b('\u0003')), "tor network is unreachable");
|
||||
map.put(Byte.valueOf(b('\u0004')), "tor host is unreachable");
|
||||
map.put(Byte.valueOf(b('\u0005')), "tor connection refused");
|
||||
map.put(Byte.valueOf(b('\u0006')), "tor TTL expired");
|
||||
map.put(Byte.valueOf(b('\u0007')), "tor command not supported");
|
||||
map.put(Byte.valueOf(b('\u0008')), "tor address type not supported");
|
||||
map.put(b('\u0000'), "tor succeeded");
|
||||
map.put(b('\u0001'), "tor general error");
|
||||
map.put(b('\u0002'), "tor not allowed");
|
||||
map.put(b('\u0003'), "tor network is unreachable");
|
||||
map.put(b('\u0004'), "tor host is unreachable");
|
||||
map.put(b('\u0005'), "tor connection refused");
|
||||
map.put(b('\u0006'), "tor TTL expired");
|
||||
map.put(b('\u0007'), "tor command not supported");
|
||||
map.put(b('\u0008'), "tor address type not supported");
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs DNS lookup and returns a single InetAddress
|
||||
*/
|
||||
public static InetAddress lookup(Socks5Proxy proxy, String host) throws Exception {
|
||||
Logger log = LoggerFactory.getLogger(DnsLookupTor.class);
|
||||
public static InetAddress lookup(Socks5Proxy proxy, String host) throws DnsLookupException {
|
||||
try {
|
||||
log.debug("Resolving {} over tor.", (Object)host);
|
||||
return DnsLookupTor.doLookup(proxy, host);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Error resolving " + host + ". Exception:\n" + e.toString());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
// note: This is creating a new connection to our proxy, without any authentication.
|
||||
// This works fine when connecting to bitsquare's internal Tor proxy, but
|
||||
// would fail if user has configured an external proxy that requires auth.
|
||||
// It would be much better to use the already connected proxy socket, but when I
|
||||
// tried that I get weird errors and the lookup fails.
|
||||
//
|
||||
// So this is an area for future improvement.
|
||||
Socket proxySocket = new Socket(proxy.getInetAddress(), proxy.getPort());
|
||||
|
||||
/**
|
||||
* The actual lookup is performed here.
|
||||
*/
|
||||
private static InetAddress doLookup(Socks5Proxy proxy, String host) throws Exception {
|
||||
|
||||
// note: This is creating a new connection to our proxy, without any authentication.
|
||||
// This works fine when connecting to bitsquare's internal Tor proxy, but
|
||||
// would fail if user has configured an external proxy that requires auth.
|
||||
// It would be much better to use the already connected proxy socket, but when I
|
||||
// tried that I get weird errors and the lookup fails.
|
||||
//
|
||||
// So this is an area for future improvement.
|
||||
Socket proxySocket = new Socket(proxy.getInetAddress(), proxy.getPort());
|
||||
|
||||
proxySocket.getOutputStream().write(new byte[]{b('\u0005'), b('\u0001'), b('\u0000')});
|
||||
byte[] buf = new byte[2];
|
||||
proxySocket.getInputStream().read(buf);
|
||||
|
||||
if (buf[0] != b('\u0005')) {
|
||||
throw new Exception("Invalid Proxy Response");
|
||||
}
|
||||
if (buf[1] != b('\u0000')) {
|
||||
throw new Exception("Unrecognized Tor Auth Method");
|
||||
}
|
||||
|
||||
byte[] hostBytes = host.getBytes();
|
||||
buf = new byte[7 + hostBytes.length];
|
||||
buf[0] = b('\u0005');
|
||||
buf[1] = b('\u00f0');
|
||||
buf[2] = b('\u0000');
|
||||
buf[3] = b('\u0003');
|
||||
buf[4] = (byte)hostBytes.length;
|
||||
System.arraycopy(hostBytes, 0, buf, 5, hostBytes.length);
|
||||
buf[5 + hostBytes.length] = 0;
|
||||
|
||||
proxySocket.getOutputStream().write(buf);
|
||||
|
||||
buf = new byte[4];
|
||||
proxySocket.getInputStream().read(buf);
|
||||
|
||||
if (buf[0] != b('\u0005')) {
|
||||
throw new Exception("Invalid Tor Proxy Response");
|
||||
}
|
||||
|
||||
if (buf[1] != b('\u0000')) {
|
||||
if (!torStatusErrors.containsKey(Byte.valueOf(buf[1]))) {
|
||||
throw new Exception("Invalid Tor Proxy Response");
|
||||
proxySocket.getOutputStream().write(new byte[]{b('\u0005'), b('\u0001'), b('\u0000')});
|
||||
byte[] buf = new byte[2];
|
||||
proxySocket.getInputStream().read(buf);
|
||||
|
||||
if (buf[0] != b('\u0005')) {
|
||||
throw new DnsLookupException("Invalid Proxy Response");
|
||||
}
|
||||
throw new Exception(torStatusErrors.get(Byte.valueOf(buf[1])));
|
||||
if (buf[1] != b('\u0000')) {
|
||||
throw new DnsLookupException("Unrecognized Tor Auth Method");
|
||||
}
|
||||
|
||||
byte[] hostBytes = host.getBytes();
|
||||
buf = new byte[7 + hostBytes.length];
|
||||
buf[0] = b('\u0005');
|
||||
buf[1] = b('\u00f0');
|
||||
buf[2] = b('\u0000');
|
||||
buf[3] = b('\u0003');
|
||||
buf[4] = (byte) hostBytes.length;
|
||||
System.arraycopy(hostBytes, 0, buf, 5, hostBytes.length);
|
||||
buf[5 + hostBytes.length] = 0;
|
||||
|
||||
proxySocket.getOutputStream().write(buf);
|
||||
|
||||
buf = new byte[4];
|
||||
int bytesRead = proxySocket.getInputStream().read(buf);
|
||||
|
||||
// TODO: Should not be a length check here as well?
|
||||
/* if (bytesRead != 4)
|
||||
throw new DnsLookupException("Invalid Tor Address Response");*/
|
||||
|
||||
|
||||
if (buf[0] != b('\u0005'))
|
||||
throw new DnsLookupException("Invalid Tor Proxy Response");
|
||||
|
||||
if (buf[1] != b('\u0000')) {
|
||||
if (!torStatusErrors.containsKey(buf[1])) {
|
||||
throw new DnsLookupException("Invalid Tor Proxy Response");
|
||||
}
|
||||
throw new DnsLookupException(torStatusErrors.get(buf[1]));
|
||||
}
|
||||
|
||||
if (buf[3] != b('\u0001'))
|
||||
throw new DnsLookupException(torStatusErrors.get(b('\u0001')));
|
||||
|
||||
buf = new byte[4];
|
||||
bytesRead = proxySocket.getInputStream().read(buf);
|
||||
|
||||
if (bytesRead != 4)
|
||||
throw new DnsLookupException("Invalid Tor Address Response");
|
||||
|
||||
return InetAddress.getByAddress(buf);
|
||||
} catch (IOException | DnsLookupException e) {
|
||||
log.warn("Error resolving " + host + ". Exception:\n" + e.toString());
|
||||
throw new DnsLookupException(e);
|
||||
}
|
||||
|
||||
if (buf[3] != b('\u0001')) {
|
||||
throw new Exception(torStatusErrors.get(Byte.valueOf(b('\u0001'))));
|
||||
}
|
||||
|
||||
buf = new byte[4];
|
||||
int bytesRead = proxySocket.getInputStream().read(buf);
|
||||
|
||||
if (bytesRead != 4) {
|
||||
throw new Exception("Invalid Tor Address Response");
|
||||
}
|
||||
|
||||
InetAddress addr = InetAddress.getByAddress(buf);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* so we can have prettier code without a bunch of casts.
|
||||
*/
|
||||
private static byte b(char c) {
|
||||
return (byte)c;
|
||||
return (byte) c;
|
||||
}
|
||||
}
|
@ -11,5 +11,6 @@ public class NetworkOptionKeys {
|
||||
public static final String BAN_LIST = "banList";
|
||||
public static final String SOCKS_5_PROXY_BTC_ADDRESS = "socks5ProxyBtcAddress";
|
||||
public static final String SOCKS_5_PROXY_HTTP_ADDRESS = "socks5ProxyHttpAddress";
|
||||
|
||||
public static final String SOCKS5_DISCOVER_MODE = "socks5DiscoverMode";
|
||||
|
||||
}
|
||||
|
@ -17,34 +17,41 @@
|
||||
|
||||
package io.bitsquare.network;
|
||||
|
||||
import com.runjva.sourceforge.jsocks.protocol.*;
|
||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.net.discovery.DnsDiscovery;
|
||||
import org.bitcoinj.net.discovery.MultiplexingDiscovery;
|
||||
import org.bitcoinj.net.discovery.PeerDiscovery;
|
||||
import org.bitcoinj.net.discovery.PeerDiscoveryException;
|
||||
import org.bitcoinj.utils.ContextPropagatingThreadFactory;
|
||||
import org.bitcoinj.utils.DaemonThreadFactory;
|
||||
|
||||
import org.bitcoinj.net.discovery.*;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.utils.*;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Supports peer discovery through DNS over Socks5 proxy with RESOLVE DNS extension.</p>
|
||||
*
|
||||
* <p>
|
||||
* (As of this writing, only Tor is known to support the RESOLVE DNS extension.)
|
||||
*
|
||||
* <p>
|
||||
* <p>Failure to resolve individual host names will not cause an Exception to be thrown.
|
||||
* However, if all hosts passed fail to resolve a PeerDiscoveryException will be thrown during getPeers().
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <p>DNS seeds do not attempt to enumerate every peer on the network. {@link DnsDiscovery#getPeers(long, java.util.concurrent.TimeUnit)}
|
||||
* will return up to 30 random peers from the set of those returned within the timeout period. If you want more peers
|
||||
* to connect to, you need to discover them via other means (like addr broadcasts).</p>
|
||||
*/
|
||||
public class Socks5DnsDiscovery extends MultiplexingDiscovery {
|
||||
|
||||
|
||||
private Socks5Proxy proxy;
|
||||
|
||||
|
||||
/**
|
||||
* Supports finding peers through DNS A records. Community run DNS entry points will be used.
|
||||
*
|
||||
@ -58,7 +65,7 @@ public class Socks5DnsDiscovery extends MultiplexingDiscovery {
|
||||
* Supports finding peers through DNS A records.
|
||||
*
|
||||
* @param dnsSeeds Host names to be examined for seed addresses.
|
||||
* @param params Network parameters to be used for port information.
|
||||
* @param params Network parameters to be used for port information.
|
||||
*/
|
||||
public Socks5DnsDiscovery(Socks5Proxy proxy, String[] dnsSeeds, NetworkParameters params) {
|
||||
super(params, buildDiscoveries(proxy, params, dnsSeeds));
|
||||
@ -68,9 +75,10 @@ public class Socks5DnsDiscovery extends MultiplexingDiscovery {
|
||||
private static List<PeerDiscovery> buildDiscoveries(Socks5Proxy proxy, NetworkParameters params, String[] seeds) {
|
||||
List<PeerDiscovery> discoveries = new ArrayList<PeerDiscovery>(seeds.length);
|
||||
for (String seed : seeds) {
|
||||
if(seed == "dnsseed.bluematt.me") {
|
||||
continue; // this dns is known to fail with tor-resolve because it returns too many addrs.
|
||||
// we avoid adding it in order to prevent ugly log messages.
|
||||
if ("dnsseed.bluematt.me".equals(seed)) {
|
||||
// this dns is known to fail with tor-resolve because it returns too many addrs.
|
||||
// we avoid adding it in order to prevent ugly log messages.
|
||||
continue;
|
||||
}
|
||||
discoveries.add(new Socks5DnsSeedDiscovery(proxy, params, seed));
|
||||
}
|
||||
@ -81,15 +89,15 @@ public class Socks5DnsDiscovery extends MultiplexingDiscovery {
|
||||
protected ExecutorService createExecutor() {
|
||||
// Attempted workaround for reported bugs on Linux in which gethostbyname does not appear to be properly
|
||||
// thread safe and can cause segfaults on some libc versions.
|
||||
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
if (Utilities.isLinux())
|
||||
return Executors.newSingleThreadExecutor(new ContextPropagatingThreadFactory("DNS seed lookups"));
|
||||
}
|
||||
else {
|
||||
else
|
||||
return Executors.newFixedThreadPool(seeds.size(), new DaemonThreadFactory("DNS seed lookups"));
|
||||
}
|
||||
}
|
||||
|
||||
/** Implements discovery from a single DNS host over Socks5 proxy with RESOLVE DNS extension. */
|
||||
/**
|
||||
* Implements discovery from a single DNS host over Socks5 proxy with RESOLVE DNS extension.
|
||||
*/
|
||||
public static class Socks5DnsSeedDiscovery implements PeerDiscovery {
|
||||
private final String hostname;
|
||||
private final NetworkParameters params;
|
||||
@ -108,15 +116,15 @@ public class Socks5DnsDiscovery extends MultiplexingDiscovery {
|
||||
public InetSocketAddress[] getPeers(long timeoutValue, TimeUnit timeoutUnit) throws PeerDiscoveryException {
|
||||
try {
|
||||
InetSocketAddress addr = new InetSocketAddress(DnsLookupTor.lookup(proxy, hostname), params.getPort());
|
||||
return new InetSocketAddress[] {addr};
|
||||
}
|
||||
catch(Exception e) {
|
||||
return new InetSocketAddress[]{addr};
|
||||
} catch (Exception e) {
|
||||
throw new PeerDiscoveryException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
//TODO should we add a DnsLookupTor.shutdown() ?
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,17 +18,15 @@
|
||||
package io.bitsquare.network;
|
||||
|
||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||
import com.runjva.sourceforge.jsocks.protocol.SocksSocket;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.net.discovery.PeerDiscovery;
|
||||
import org.bitcoinj.net.discovery.PeerDiscoveryException;
|
||||
import org.bitcoinj.net.discovery.SeedPeers;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
@ -36,39 +34,35 @@ import java.util.Arrays;
|
||||
* which can be enabled/disabled via constructor flag.
|
||||
*/
|
||||
public class Socks5MultiDiscovery implements PeerDiscovery {
|
||||
|
||||
public static final int SOCKS5_DISCOVER_ADDR = 0x0001;
|
||||
public static final int SOCKS5_DISCOVER_DNS = 0x0010;
|
||||
public static final int SOCKS5_DISCOVER_ONION = 0x0100;
|
||||
public static final int SOCKS5_DISCOVER_ALL = 0x1111;
|
||||
|
||||
private ArrayList<PeerDiscovery> discoveryList;
|
||||
|
||||
|
||||
public static final int SOCKS5_DISCOVER_ADDR = 0x0001;
|
||||
public static final int SOCKS5_DISCOVER_DNS = 0x0010;
|
||||
public static final int SOCKS5_DISCOVER_ONION = 0x0100;
|
||||
public static final int SOCKS5_DISCOVER_ALL = 0x1111;
|
||||
|
||||
private final ArrayList<PeerDiscovery> discoveryList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Supports finding peers by hostname over a socks5 proxy.
|
||||
*
|
||||
* @param Socks5Proxy proxy the socks5 proxy to connect over.
|
||||
* @param NetworkParameters param to be used for seed and port information.
|
||||
* @param proxy proxy the socks5 proxy to connect over.
|
||||
* @param params param to be used for seed and port information.
|
||||
* @param mode specify discovery mode, OR'd together. one or more of:
|
||||
* SOCKS5_DISCOVER_ADDR
|
||||
* SOCKS5_DISCOVER_DNS
|
||||
* SOCKS5_DISCOVER_ONION
|
||||
* SOCKS5_DISCOVER_ALL
|
||||
* SOCKS5_DISCOVER_ADDR
|
||||
* SOCKS5_DISCOVER_DNS
|
||||
* SOCKS5_DISCOVER_ONION
|
||||
* SOCKS5_DISCOVER_ALL
|
||||
*/
|
||||
public Socks5MultiDiscovery(Socks5Proxy proxy, NetworkParameters params, int mode) {
|
||||
|
||||
discoveryList = new ArrayList<PeerDiscovery>();
|
||||
|
||||
if( (mode & SOCKS5_DISCOVER_ONION) != 0) {
|
||||
if ((mode & SOCKS5_DISCOVER_ONION) != 0)
|
||||
discoveryList.add(new Socks5SeedOnionDiscovery(proxy, params));
|
||||
}
|
||||
if( (mode & SOCKS5_DISCOVER_ADDR) != 0) {
|
||||
|
||||
if ((mode & SOCKS5_DISCOVER_ADDR) != 0)
|
||||
// note: SeedPeers does not perform any network operations, so does not use proxy.
|
||||
discoveryList.add(new SeedPeers(params));
|
||||
}
|
||||
if( (mode & SOCKS5_DISCOVER_DNS) != 0) {
|
||||
discoveryList.add(new SeedPeers(params));
|
||||
|
||||
if ((mode & SOCKS5_DISCOVER_DNS) != 0)
|
||||
discoveryList.add(new Socks5DnsDiscovery(proxy, params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,17 +70,18 @@ public class Socks5MultiDiscovery implements PeerDiscovery {
|
||||
*/
|
||||
@Override
|
||||
public InetSocketAddress[] getPeers(long timeoutValue, TimeUnit timeoutUnit) throws PeerDiscoveryException {
|
||||
ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
|
||||
|
||||
ArrayList<InetSocketAddress> list = new ArrayList<>();
|
||||
|
||||
for (PeerDiscovery discovery : discoveryList) {
|
||||
list.addAll(Arrays.asList(discovery.getPeers(timeoutValue, timeoutUnit)));
|
||||
}
|
||||
|
||||
|
||||
return list.toArray(new InetSocketAddress[list.size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
//TODO should we add a DnsLookupTor.shutdown() ?
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -18,21 +18,14 @@
|
||||
package io.bitsquare.network;
|
||||
|
||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||
import com.runjva.sourceforge.jsocks.protocol.SocksSocket;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.net.discovery.PeerDiscovery;
|
||||
import org.bitcoinj.net.discovery.PeerDiscoveryException;
|
||||
import org.bitcoinj.params.MainNetParams;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
import org.bitcoinj.params.TestNet3Params;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
@ -47,8 +40,8 @@ public class Socks5SeedOnionDiscovery implements PeerDiscovery {
|
||||
/**
|
||||
* Supports finding peers by hostname over a socks5 proxy.
|
||||
*
|
||||
* @param Socks5Proxy proxy the socks5 proxy to connect over.
|
||||
* @param NetworkParameters param to be used for seed and port information.
|
||||
* @param proxy proxy the socks5 proxy to connect over.
|
||||
* @param params param to be used for seed and port information.
|
||||
*/
|
||||
public Socks5SeedOnionDiscovery(Socks5Proxy proxy, NetworkParameters params) {
|
||||
|
||||
@ -141,5 +134,6 @@ public class Socks5SeedOnionDiscovery implements PeerDiscovery {
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
//TODO should we add a DnsLookupTor.shutdown() ?
|
||||
}
|
||||
}
|
@ -55,6 +55,9 @@ public class P2PModule extends AppModule {
|
||||
Integer maxConnections = env.getProperty(NetworkOptionKeys.MAX_CONNECTIONS, int.class, P2PService.MAX_CONNECTIONS_DEFAULT);
|
||||
bind(int.class).annotatedWith(Names.named(NetworkOptionKeys.MAX_CONNECTIONS)).toInstance(maxConnections);
|
||||
|
||||
String socks5DiscoverMode = env.getProperty(NetworkOptionKeys.SOCKS5_DISCOVER_MODE, String.class, "ALL");
|
||||
bind(String.class).annotatedWith(Names.named(NetworkOptionKeys.SOCKS5_DISCOVER_MODE)).toInstance(socks5DiscoverMode);
|
||||
|
||||
Integer networkId = env.getProperty(NetworkOptionKeys.NETWORK_ID, int.class, 1);
|
||||
bind(int.class).annotatedWith(Names.named(NetworkOptionKeys.NETWORK_ID)).toInstance(networkId);
|
||||
bindConstant().annotatedWith(named(NetworkOptionKeys.SEED_NODES_KEY)).to(env.getRequiredProperty(NetworkOptionKeys.SEED_NODES_KEY));
|
||||
|
Loading…
Reference in New Issue
Block a user