Support tor w/either Netlayer or direct bind to SOCKS5 data port

This commit is contained in:
fa2a5qj3 2024-07-29 07:54:53 -04:00 committed by GitHub
parent 84a2828e90
commit 3d44f3777c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 377 additions and 154 deletions

View file

@ -77,6 +77,7 @@ public class Config {
public static final String SEED_NODES = "seedNodes";
public static final String BAN_LIST = "banList";
public static final String NODE_PORT = "nodePort";
public static final String HIDDEN_SERVICE_ADDRESS = "hiddenServiceAddress";
public static final String USE_LOCALHOST_FOR_P2P = "useLocalhostForP2P";
public static final String MAX_CONNECTIONS = "maxConnections";
public static final String SOCKS_5_PROXY_XMR_ADDRESS = "socks5ProxyXmrAddress";
@ -122,6 +123,7 @@ public class Config {
public static final String DEFAULT_REGTEST_HOST = "none";
public static final int DEFAULT_NUM_CONNECTIONS_FOR_BTC = 9; // down from BitcoinJ default of 12
static final String DEFAULT_CONFIG_FILE_NAME = "haveno.properties";
public static final String UNSPECIFIED_HIDDENSERVICE_ADDRESS = "placeholder.onion";
// Static fields that provide access to Config properties in locations where injecting
// a Config instance is not feasible. See Javadoc for corresponding static accessors.
@ -151,6 +153,7 @@ public class Config {
public final File appDataDir;
public final int walletRpcBindPort;
public final int nodePort;
public final String hiddenServiceAddress;
public final int maxMemory;
public final String logLevel;
public final List<String> bannedXmrNodes;
@ -286,6 +289,12 @@ public class Config {
.ofType(Integer.class)
.defaultsTo(9999);
ArgumentAcceptingOptionSpec<String> hiddenServiceAddressOpt =
parser.accepts(HIDDEN_SERVICE_ADDRESS, "Hidden Service Address to listen on")
.withRequiredArg()
.ofType(String.class)
.defaultsTo(UNSPECIFIED_HIDDENSERVICE_ADDRESS);
ArgumentAcceptingOptionSpec<Integer> walletRpcBindPortOpt =
parser.accepts(WALLET_RPC_BIND_PORT, "Port to bind the wallet RPC on")
.withRequiredArg()
@ -670,6 +679,7 @@ public class Config {
this.helpRequested = options.has(helpOpt);
this.configFile = configFile;
this.nodePort = options.valueOf(nodePortOpt);
this.hiddenServiceAddress = options.valueOf(hiddenServiceAddressOpt);
this.walletRpcBindPort = options.valueOf(walletRpcBindPortOpt);
this.maxMemory = options.valueOf(maxMemoryOpt);
this.logLevel = options.valueOf(logLevelOpt);

View file

@ -28,8 +28,10 @@ import haveno.network.p2p.network.LocalhostNetworkNode;
import haveno.network.p2p.network.NetworkNode;
import haveno.network.p2p.network.NewTor;
import haveno.network.p2p.network.RunningTor;
import haveno.network.p2p.network.DirectBindTor;
import haveno.network.p2p.network.TorMode;
import haveno.network.p2p.network.TorNetworkNode;
import haveno.network.p2p.network.TorNetworkNodeDirectBind;
import haveno.network.p2p.network.TorNetworkNodeNetlayer;
import java.io.File;
import javax.annotation.Nullable;
@ -44,6 +46,7 @@ public class NetworkNodeProvider implements Provider<NetworkNode> {
@Named(Config.MAX_CONNECTIONS) int maxConnections,
@Named(Config.USE_LOCALHOST_FOR_P2P) boolean useLocalhostForP2P,
@Named(Config.NODE_PORT) int port,
@Named(Config.HIDDEN_SERVICE_ADDRESS) String hiddenServiceAddress,
@Named(Config.TOR_DIR) File torDir,
@Nullable @Named(Config.TORRC_FILE) File torrcFile,
@Named(Config.TORRC_OPTIONS) String torrcOptions,
@ -62,10 +65,15 @@ public class NetworkNodeProvider implements Provider<NetworkNode> {
torrcOptions,
controlHost,
controlPort,
hiddenServiceAddress,
password,
cookieFile,
useSafeCookieAuthentication);
networkNode = new TorNetworkNode(port, networkProtoResolver, streamIsolation, torMode, banFilter, maxConnections, controlHost);
if (torMode instanceof NewTor || torMode instanceof RunningTor) {
networkNode = new TorNetworkNodeNetlayer(port, networkProtoResolver, torMode, banFilter, maxConnections, streamIsolation, controlHost);
} else {
networkNode = new TorNetworkNodeDirectBind(port, networkProtoResolver, banFilter, maxConnections, hiddenServiceAddress);
}
}
}
@ -75,12 +83,19 @@ public class NetworkNodeProvider implements Provider<NetworkNode> {
String torrcOptions,
String controlHost,
int controlPort,
String hiddenServiceAddress,
String password,
@Nullable File cookieFile,
boolean useSafeCookieAuthentication) {
return controlPort != Config.UNSPECIFIED_PORT ?
new RunningTor(torDir, controlHost, controlPort, password, cookieFile, useSafeCookieAuthentication) :
new NewTor(torDir, torrcFile, torrcOptions, bridgeAddressProvider);
if (!hiddenServiceAddress.equals(Config.UNSPECIFIED_HIDDENSERVICE_ADDRESS)) {
return new DirectBindTor();
}
else if (controlPort != Config.UNSPECIFIED_PORT) {
return new RunningTor(torDir, controlHost, controlPort, password, cookieFile, useSafeCookieAuthentication);
}
else {
return new NewTor(torDir, torrcFile, torrcOptions, bridgeAddressProvider);
}
}
@Override

View file

@ -26,6 +26,7 @@ import haveno.common.config.Config;
import static haveno.common.config.Config.BAN_LIST;
import static haveno.common.config.Config.MAX_CONNECTIONS;
import static haveno.common.config.Config.NODE_PORT;
import static haveno.common.config.Config.HIDDEN_SERVICE_ADDRESS;
import static haveno.common.config.Config.REPUBLISH_MAILBOX_ENTRIES;
import static haveno.common.config.Config.SOCKS_5_PROXY_HTTP_ADDRESS;
import static haveno.common.config.Config.SOCKS_5_PROXY_XMR_ADDRESS;
@ -87,6 +88,7 @@ public class P2PModule extends AppModule {
bind(File.class).annotatedWith(named(TOR_DIR)).toInstance(config.torDir);
bind(int.class).annotatedWith(named(NODE_PORT)).toInstance(config.nodePort);
bind(String.class).annotatedWith(named(HIDDEN_SERVICE_ADDRESS)).toInstance(config.hiddenServiceAddress);
bindConstant().annotatedWith(named(MAX_CONNECTIONS)).to(config.maxConnections);

View file

@ -0,0 +1,22 @@
package haveno.network.p2p.network;
import lombok.extern.slf4j.Slf4j;
import org.berndpruenster.netlayer.tor.Tor;
@Slf4j
public class DirectBindTor extends TorMode {
public DirectBindTor() {
super(null);
}
@Override
public Tor getTor() {
return null;
}
@Override
public String getHiddenServiceDirectory() {
return null;
}
}

View file

@ -18,50 +18,26 @@
package haveno.network.p2p.network;
import haveno.network.p2p.NodeAddress;
import haveno.network.utils.Utils;
import haveno.common.Timer;
import haveno.common.UserThread;
import haveno.common.proto.network.NetworkProtoResolver;
import haveno.common.util.SingleThreadExecutorUtils;
import org.berndpruenster.netlayer.tor.HiddenServiceSocket;
import org.berndpruenster.netlayer.tor.Tor;
import org.berndpruenster.netlayer.tor.TorCtlException;
import org.berndpruenster.netlayer.tor.TorSocket;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
import java.security.SecureRandom;
import java.net.Socket;
import java.io.IOException;
import java.util.Base64;
import java.util.concurrent.ExecutorService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
@Slf4j
public class TorNetworkNode extends NetworkNode {
private static final long SHUT_DOWN_TIMEOUT = 2;
public abstract class TorNetworkNode extends NetworkNode {
private final String torControlHost;
private HiddenServiceSocket hiddenServiceSocket;
private Timer shutDownTimeoutTimer;
private Tor tor;
private TorMode torMode;
private boolean streamIsolation;
private Socks5Proxy socksProxy;
private boolean shutDownInProgress;
private boolean shutDownComplete;
private final ExecutorService executor;
protected final ExecutorService executor;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@ -69,15 +45,9 @@ public class TorNetworkNode extends NetworkNode {
public TorNetworkNode(int servicePort,
NetworkProtoResolver networkProtoResolver,
boolean useStreamIsolation,
TorMode torMode,
@Nullable BanFilter banFilter,
int maxConnections, String torControlHost) {
int maxConnections) {
super(servicePort, networkProtoResolver, banFilter, maxConnections);
this.torMode = torMode;
this.streamIsolation = useStreamIsolation;
this.torControlHost = torControlHost;
executor = SingleThreadExecutorUtils.getSingleThreadExecutor("StartTor");
}
@ -87,121 +57,19 @@ public class TorNetworkNode extends NetworkNode {
@Override
public void start(@Nullable SetupListener setupListener) {
torMode.doRollingBackup();
if (setupListener != null)
addSetupListener(setupListener);
createTorAndHiddenService(Utils.findFreeSystemPort(), servicePort);
}
@Override
protected Socket createSocket(NodeAddress peerNodeAddress) throws IOException {
checkArgument(peerNodeAddress.getHostName().endsWith(".onion"), "PeerAddress is not an onion address");
// If streamId is null stream isolation gets deactivated.
// Hidden services use stream isolation by default, so we pass null.
return new TorSocket(peerNodeAddress.getHostName(), peerNodeAddress.getPort(), torControlHost, null);
}
public Socks5Proxy getSocksProxy() {
try {
String stream = null;
if (streamIsolation) {
byte[] bytes = new byte[512]; // tor.getProxy creates a Sha256 hash
new SecureRandom().nextBytes(bytes);
stream = Base64.getEncoder().encodeToString(bytes);
}
if (socksProxy == null || streamIsolation) {
tor = Tor.getDefault();
socksProxy = tor != null ? tor.getProxy(torControlHost, stream) : null;
}
return socksProxy;
} catch (Throwable t) {
log.error("Error at getSocksProxy", t);
return null;
}
createTorAndHiddenService();
}
public void shutDown(@Nullable Runnable shutDownCompleteHandler) {
log.info("TorNetworkNode shutdown started");
if (shutDownComplete) {
log.info("TorNetworkNode shutdown already completed");
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
return;
}
if (shutDownInProgress) {
log.warn("Ignoring request to shut down because shut down is in progress");
return;
}
shutDownInProgress = true;
shutDownTimeoutTimer = UserThread.runAfter(() -> {
log.error("A timeout occurred at shutDown");
shutDownComplete = true;
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
executor.shutdownNow();
}, SHUT_DOWN_TIMEOUT);
super.shutDown(() -> {
try {
tor = Tor.getDefault();
if (tor != null) {
tor.shutdown();
tor = null;
log.info("Tor shutdown completed");
}
executor.shutdownNow();
} catch (Throwable e) {
log.error("Shutdown torNetworkNode failed with exception", e);
} finally {
shutDownTimeoutTimer.stop();
shutDownComplete = true;
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
}
});
super.shutDown(shutDownCompleteHandler);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Create tor and hidden service
///////////////////////////////////////////////////////////////////////////////////////////
public abstract Socks5Proxy getSocksProxy();
private void createTorAndHiddenService(int localPort, int servicePort) {
executor.submit(() -> {
try {
Tor.setDefault(torMode.getTor());
long ts = System.currentTimeMillis();
hiddenServiceSocket = new HiddenServiceSocket(localPort, torMode.getHiddenServiceDirectory(), servicePort);
nodeAddressProperty.set(new NodeAddress(hiddenServiceSocket.getServiceName() + ":" + hiddenServiceSocket.getHiddenServicePort()));
UserThread.execute(() -> setupListeners.forEach(SetupListener::onTorNodeReady));
hiddenServiceSocket.addReadyListener(socket -> {
log.info("\n################################################################\n" +
"Tor hidden service published after {} ms. Socket={}\n" +
"################################################################",
System.currentTimeMillis() - ts, socket);
UserThread.execute(() -> {
nodeAddressProperty.set(new NodeAddress(hiddenServiceSocket.getServiceName() + ":"
+ hiddenServiceSocket.getHiddenServicePort()));
startServer(socket);
setupListeners.forEach(SetupListener::onHiddenServicePublished);
});
return null;
});
} catch (TorCtlException e) {
log.error("Starting tor node failed", e);
if (e.getCause() instanceof IOException) {
UserThread.execute(() -> setupListeners.forEach(s -> s.onSetupFailed(new RuntimeException(e.getMessage()))));
} else {
UserThread.execute(() -> setupListeners.forEach(SetupListener::onRequestCustomBridges));
log.warn("We shutdown as starting tor with the default bridges failed. We request user to add custom bridges.");
shutDown(null);
}
} catch (IOException e) {
log.error("Could not connect to running Tor", e);
UserThread.execute(() -> setupListeners.forEach(s -> s.onSetupFailed(new RuntimeException(e.getMessage()))));
} catch (Throwable ignore) {
}
return null;
});
}
protected abstract Socket createSocket(NodeAddress peerNodeAddress) throws IOException;
protected abstract void createTorAndHiddenService();
}

View file

@ -0,0 +1,113 @@
package haveno.network.p2p.network;
import haveno.common.util.Hex;
import haveno.network.p2p.NodeAddress;
import haveno.common.UserThread;
import haveno.common.proto.network.NetworkProtoResolver;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
import java.net.Socket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
@Slf4j
public class TorNetworkNodeDirectBind extends TorNetworkNode {
private static final int TOR_DATA_PORT = 9050; // TODO: config option?
private final String serviceAddress;
public TorNetworkNodeDirectBind(int servicePort,
NetworkProtoResolver networkProtoResolver,
@Nullable BanFilter banFilter,
int maxConnections, String hiddenServiceAddress) {
super(servicePort, networkProtoResolver, banFilter, maxConnections);
this.serviceAddress = hiddenServiceAddress;
}
@Override
public void shutDown(@Nullable Runnable shutDownCompleteHandler) {
super.shutDown(() -> {
log.info("TorNetworkNode shutdown already completed");
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
});
}
@Override
public Socks5Proxy getSocksProxy() {
Socks5Proxy proxy = new Socks5Proxy(InetAddress.getLoopbackAddress(), TOR_DATA_PORT);
proxy.resolveAddrLocally(false);
return proxy;
}
@Override
protected Socket createSocket(NodeAddress peerNodeAddress) throws IOException {
// https://www.ietf.org/rfc1928.txt SOCKS5 Protocol
try {
checkArgument(peerNodeAddress.getHostName().endsWith(".onion"), "PeerAddress is not an onion address");
Socket sock = new Socket(InetAddress.getLoopbackAddress(), TOR_DATA_PORT);
sock.getOutputStream().write(Hex.decode("050100"));
String response = Hex.encode(sock.getInputStream().readNBytes(2));
if (!response.equalsIgnoreCase("0500")) {
return null;
}
String connect_details = "050100033E" + Hex.encode(peerNodeAddress.getHostName().getBytes(StandardCharsets.UTF_8));
StringBuilder connect_port = new StringBuilder(Integer.toHexString(peerNodeAddress.getPort()));
while (connect_port.length() < 4) connect_port.insert(0, "0");
connect_details = connect_details + connect_port;
sock.getOutputStream().write(Hex.decode(connect_details));
response = Hex.encode(sock.getInputStream().readNBytes(10));
if (response.substring(0, 2).equalsIgnoreCase("05") && response.substring(2, 4).equalsIgnoreCase("00")) {
return sock; // success
}
if (response.substring(2, 4).equalsIgnoreCase("04")) {
log.warn("Host unreachable: {}", peerNodeAddress);
} else {
log.warn("SOCKS error code received {} expected 00", response.substring(2, 4));
}
if (!response.substring(0, 2).equalsIgnoreCase("05")) {
log.warn("unexpected response, this isn't a SOCKS5 proxy?: {} {}", response, response.substring(0, 2));
}
} catch (Exception e) {
log.warn(e.toString());
}
throw new IOException("createSocket failed");
}
@Override
protected void createTorAndHiddenService() {
executor.submit(() -> {
try {
// listener for incoming messages at the hidden service
ServerSocket socket = new ServerSocket(servicePort);
nodeAddressProperty.set(new NodeAddress(serviceAddress + ":" + servicePort));
log.info("\n################################################################\n" +
"Tor hidden service published: {} Port: {}\n" +
"################################################################",
serviceAddress, servicePort);
UserThread.execute(() -> setupListeners.forEach(SetupListener::onTorNodeReady));
UserThread.runAfter(() -> {
nodeAddressProperty.set(new NodeAddress(serviceAddress + ":" + servicePort));
startServer(socket);
setupListeners.forEach(SetupListener::onHiddenServicePublished);
}, 3);
return null;
} catch (IOException e) {
log.error("Could not connect to external Tor", e);
UserThread.execute(() -> setupListeners.forEach(s -> s.onSetupFailed(new RuntimeException(e.getMessage()))));
}
return null;
});
}
}

View file

@ -0,0 +1,174 @@
package haveno.network.p2p.network;
import haveno.common.Timer;
import haveno.network.p2p.NodeAddress;
import haveno.common.UserThread;
import haveno.common.proto.network.NetworkProtoResolver;
import haveno.network.utils.Utils;
import org.berndpruenster.netlayer.tor.HiddenServiceSocket;
import org.berndpruenster.netlayer.tor.Tor;
import org.berndpruenster.netlayer.tor.TorCtlException;
import org.berndpruenster.netlayer.tor.TorSocket;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
import java.security.SecureRandom;
import java.net.Socket;
import java.io.IOException;
import java.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
@Slf4j
public class TorNetworkNodeNetlayer extends TorNetworkNode {
private static final long SHUT_DOWN_TIMEOUT = 2;
private HiddenServiceSocket hiddenServiceSocket;
private boolean streamIsolation;
private Socks5Proxy socksProxy;
protected TorMode torMode;
private Tor tor;
private final String torControlHost;
private Timer shutDownTimeoutTimer;
private boolean shutDownInProgress;
private boolean shutDownComplete;
public TorNetworkNodeNetlayer(int servicePort,
NetworkProtoResolver networkProtoResolver,
TorMode torMode,
@Nullable BanFilter banFilter,
int maxConnections,
boolean useStreamIsolation,
String torControlHost) {
super(servicePort, networkProtoResolver, banFilter, maxConnections);
this.torControlHost = torControlHost;
this.streamIsolation = useStreamIsolation;
this.torMode = torMode;
}
@Override
public void start(@Nullable SetupListener setupListener) {
torMode.doRollingBackup();
super.start(setupListener);
}
@Override
public void shutDown(@Nullable Runnable shutDownCompleteHandler) {
log.info("TorNetworkNode shutdown started");
if (shutDownComplete) {
log.info("TorNetworkNode shutdown already completed");
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
return;
}
if (shutDownInProgress) {
log.warn("Ignoring request to shut down because shut down is in progress");
return;
}
shutDownInProgress = true;
shutDownTimeoutTimer = UserThread.runAfter(() -> {
log.error("A timeout occurred at shutDown");
shutDownComplete = true;
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
executor.shutdownNow();
}, SHUT_DOWN_TIMEOUT);
super.shutDown(() -> {
try {
tor = Tor.getDefault();
if (tor != null) {
tor.shutdown();
tor = null;
log.info("Tor shutdown completed");
}
executor.shutdownNow();
} catch (Throwable e) {
log.error("Shutdown torNetworkNode failed with exception", e);
} finally {
shutDownTimeoutTimer.stop();
shutDownComplete = true;
if (shutDownCompleteHandler != null) shutDownCompleteHandler.run();
}
});
}
@Override
protected Socket createSocket(NodeAddress peerNodeAddress) throws IOException {
checkArgument(peerNodeAddress.getHostName().endsWith(".onion"), "PeerAddress is not an onion address");
// If streamId is null stream isolation gets deactivated.
// Hidden services use stream isolation by default, so we pass null.
return new TorSocket(peerNodeAddress.getHostName(), peerNodeAddress.getPort(), torControlHost, null);
}
@Override
public Socks5Proxy getSocksProxy() {
try {
String stream = null;
if (streamIsolation) {
byte[] bytes = new byte[512]; // tor.getProxy creates a Sha256 hash
new SecureRandom().nextBytes(bytes);
stream = Base64.getEncoder().encodeToString(bytes);
}
if (socksProxy == null || streamIsolation) {
tor = Tor.getDefault();
socksProxy = tor != null ? tor.getProxy(torControlHost, stream) : null;
}
return socksProxy;
} catch (Throwable t) {
log.error("Error at getSocksProxy", t);
return null;
}
}
@Override
protected void createTorAndHiddenService() {
int localPort = Utils.findFreeSystemPort();
executor.submit(() -> {
try {
Tor.setDefault(torMode.getTor());
long ts = System.currentTimeMillis();
hiddenServiceSocket = new HiddenServiceSocket(localPort, torMode.getHiddenServiceDirectory(), servicePort);
nodeAddressProperty.set(new NodeAddress(hiddenServiceSocket.getServiceName() + ":" + hiddenServiceSocket.getHiddenServicePort()));
UserThread.execute(() -> setupListeners.forEach(SetupListener::onTorNodeReady));
hiddenServiceSocket.addReadyListener(socket -> {
log.info("\n################################################################\n" +
"Tor hidden service published after {} ms. Socket={}\n" +
"################################################################",
System.currentTimeMillis() - ts, socket);
UserThread.execute(() -> {
nodeAddressProperty.set(new NodeAddress(hiddenServiceSocket.getServiceName() + ":"
+ hiddenServiceSocket.getHiddenServicePort()));
startServer(socket);
setupListeners.forEach(SetupListener::onHiddenServicePublished);
});
return null;
});
} catch (TorCtlException e) {
log.error("Starting tor node failed", e);
if (e.getCause() instanceof IOException) {
UserThread.execute(() -> setupListeners.forEach(s -> s.onSetupFailed(new RuntimeException(e.getMessage()))));
} else {
UserThread.execute(() -> setupListeners.forEach(SetupListener::onRequestCustomBridges));
log.warn("We shutdown as starting tor with the default bridges failed. We request user to add custom bridges.");
shutDown(null);
}
} catch (IOException e) {
log.error("Could not connect to running Tor", e);
UserThread.execute(() -> setupListeners.forEach(s -> s.onSetupFailed(new RuntimeException(e.getMessage()))));
} catch (Throwable ignore) {
}
return null;
});
}
}

View file

@ -50,8 +50,13 @@ public class TorNetworkNodeTest {
public void testTorNodeBeforeSecondReady() throws InterruptedException, IOException {
latch = new CountDownLatch(1);
int port = 9001;
TorNetworkNode node1 = new TorNetworkNode(port, TestUtils.getNetworkProtoResolver(), false,
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses), null, 12, "127.0.0.1");
TorNetworkNode node1 = new TorNetworkNodeNetlayer(port,
TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses),
null,
12,
false,
"127.0.0.1");
node1.start(new SetupListener() {
@Override
public void onTorNodeReady() {
@ -77,8 +82,13 @@ public class TorNetworkNodeTest {
latch = new CountDownLatch(1);
int port2 = 9002;
TorNetworkNode node2 = new TorNetworkNode(port2, TestUtils.getNetworkProtoResolver(), false,
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses), null, 12, "127.0.0.1");
TorNetworkNode node2 = new TorNetworkNodeNetlayer(port2,
TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses),
null,
12,
false,
"127.0.0.1");
node2.start(new SetupListener() {
@Override
public void onTorNodeReady() {
@ -135,8 +145,13 @@ public class TorNetworkNodeTest {
public void testTorNodeAfterBothReady() throws InterruptedException, IOException {
latch = new CountDownLatch(2);
int port = 9001;
TorNetworkNode node1 = new TorNetworkNode(port, TestUtils.getNetworkProtoResolver(), false,
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses), null, 12, "127.0.0.1");
TorNetworkNode node1 = new TorNetworkNodeNetlayer(port,
TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses),
null,
12,
false,
"127.0.0.1");
node1.start(new SetupListener() {
@Override
public void onTorNodeReady() {
@ -161,8 +176,12 @@ public class TorNetworkNodeTest {
});
int port2 = 9002;
TorNetworkNode node2 = new TorNetworkNode(port2, TestUtils.getNetworkProtoResolver(), false,
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses), null, 12, "127.0.0.1");
TorNetworkNode node2 = new TorNetworkNodeNetlayer(port2, TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), null, "", this::getBridgeAddresses),
null,
12,
false,
"127.0.0.1");
node2.start(new SetupListener() {
@Override
public void onTorNodeReady() {