Skip to content

Commit

Permalink
Rolling backup for external Tor
Browse files Browse the repository at this point in the history
  • Loading branch information
freimair committed Nov 25, 2018
1 parent 6eeda23 commit 3a44b36
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public NetworkNodeProvider(NetworkProtoResolver networkProtoResolver,
@Named(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE) boolean useSafeCookieAuthentication ) {
networkNode = useLocalhostForP2P ?
new LocalhostNetworkNode(address, port, networkProtoResolver) :
new TorNetworkNode(port, torDir, networkProtoResolver,
new TorNetworkNode(port, networkProtoResolver,
!controlPort.isEmpty() ?
new RunningTor(torDir, Integer.parseInt(controlPort), password, cookieFile, useSafeCookieAuthentication) :
new NewTor(torDir, torrcFile, torrcOptions, bridgeAddressProvider.getBridgeAddresses()));
Expand Down
11 changes: 10 additions & 1 deletion p2p/src/main/java/bisq/network/p2p/network/NewTor.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,23 @@
*/
public class NewTor extends TorMode {

/**
* <code>Netlayer</code> stores its hidden service files in a custom
* subdirectory of <code>$torDir/hiddenservice/</code>. Note that the
* {@link HiddenServiceSocket} does add this part on its own, hence,
* {@link NewTor#getHiddenServiceDirectory()} returns only the custom
* subdirectory (which happens to be <code>""</code>)
*/
private static final String HIDDEN_SERVICE_DIRECTORY = "hiddenservice";

private static final Logger log = LoggerFactory.getLogger(NewTor.class);

private final String torrcFile;
private final String torrcOptions;
private final Collection<String> bridgeEntries;

public NewTor(File torWorkingDirectory, String torrcFile, String torrcOptions, Collection<String> bridgeEntries) {
super(torWorkingDirectory);
super(torWorkingDirectory, HIDDEN_SERVICE_DIRECTORY);
this.torrcFile = torrcFile;
this.torrcOptions = torrcOptions;
this.bridgeEntries = bridgeEntries;
Expand Down
5 changes: 3 additions & 2 deletions p2p/src/main/java/bisq/network/p2p/network/RunningTor.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
*/
public class RunningTor extends TorMode {

private static final String EXTERNAL_TOR_HIDDEN_SERVICE = "externalTorHiddenService";
private static final Logger log = LoggerFactory.getLogger(RunningTor.class);
private final int controlPort;
private final String password;
Expand All @@ -48,7 +49,7 @@ public class RunningTor extends TorMode {

public RunningTor(final File torDir, final int controlPort, final String password, final String cookieFile,
final boolean useSafeCookieAuthentication) {
super(torDir);
super(torDir, EXTERNAL_TOR_HIDDEN_SERVICE);
this.controlPort = controlPort;
this.password = password;
this.cookieFile = new File(cookieFile);
Expand Down Expand Up @@ -80,7 +81,7 @@ else if (cookieFile.exists())

@Override
public String getHiddenServiceDirectory() {
return new File(torDir, "externalTorHiddenService").getAbsolutePath();
return new File(torDir, EXTERNAL_TOR_HIDDEN_SERVICE).getAbsolutePath();
}

}
29 changes: 26 additions & 3 deletions p2p/src/main/java/bisq/network/p2p/network/TorMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.berndpruenster.netlayer.tor.Tor;
import org.berndpruenster.netlayer.tor.TorCtlException;

import bisq.common.storage.FileUtil;

/**
* Holds information on how tor should be created and delivers a respective
* {@link Tor} object when asked.
Expand All @@ -32,17 +34,31 @@
*/
public abstract class TorMode {

/**
* The directory where the <code>private_key</code> file sits in. Kept private,
* because it is only valid for the {@link TorMode#doRollingBackup()} due to the
* inner workings of the <code>Netlayer</code> dependency.
*/
private final File hiddenServiceDirectory;
protected final File torDir;

public TorMode(File torDir) {
/**
* @param torDir points to the place, where we will persist private
* key and address data
* @param hiddenServiceDir The directory where the <code>private_key</code> file
* sits in. Note that, due to the inner workings of the
* <code>Netlayer</code> dependency, it does not
* necessarily equal
* {@link TorMode#getHiddenServiceDirectory()}.
*/
public TorMode(File torDir, String hiddenServiceDir) {
this.torDir = torDir;
this.hiddenServiceDirectory = new File(torDir, hiddenServiceDir);
}

/**
* Returns a fresh {@link Tor} object.
*
* @param torDir points to the place, where we will persist private key and
* address data
* @return a fresh instance of {@link Tor}
* @throws IOException
* @throws TorCtlException
Expand All @@ -64,4 +80,11 @@ public TorMode(File torDir) {
*/
public abstract String getHiddenServiceDirectory();

/**
* Do a rolling backup of the "private_key" file.
*/
protected void doRollingBackup() {
FileUtil.rollingBackup(hiddenServiceDirectory, "private_key", 20);
}

}
13 changes: 2 additions & 11 deletions p2p/src/main/java/bisq/network/p2p/network/TorNetworkNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import bisq.common.UserThread;
import bisq.common.app.Log;
import bisq.common.proto.network.NetworkProtoResolver;
import bisq.common.storage.FileUtil;
import bisq.common.util.Utilities;

import org.berndpruenster.netlayer.tor.HiddenServiceSocket;
Expand All @@ -47,14 +46,9 @@

import java.net.Socket;

import java.nio.file.Paths;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -74,7 +68,6 @@ public class TorNetworkNode extends NetworkNode {


private HiddenServiceSocket hiddenServiceSocket;
private final File torDir;
private Timer shutDownTimeoutTimer;
private int restartCounter;
@SuppressWarnings("FieldCanBeLocal")
Expand All @@ -87,9 +80,8 @@ public class TorNetworkNode extends NetworkNode {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////

public TorNetworkNode(int servicePort, File torDir, NetworkProtoResolver networkProtoResolver, TorMode torMode) {
public TorNetworkNode(int servicePort, NetworkProtoResolver networkProtoResolver, TorMode torMode) {
super(servicePort, networkProtoResolver);
this.torDir = torDir;
this.torMode = torMode;
}

Expand All @@ -100,8 +92,7 @@ public TorNetworkNode(int servicePort, File torDir, NetworkProtoResolver network

@Override
public void start(@Nullable SetupListener setupListener) {
final File hiddenservice = new File(Paths.get(torDir.getAbsolutePath(), "hiddenservice").toString());
FileUtil.rollingBackup(hiddenservice, "private_key", 20);
torMode.doRollingBackup();

if (setupListener != null)
addSetupListener(setupListener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ public class TorNetworkNodeTest {
public void testTorNodeBeforeSecondReady() throws InterruptedException, IOException {
latch = new CountDownLatch(1);
int port = 9001;
TorNetworkNode node1 = new TorNetworkNode(port, new File("torNode_" + port),
TestUtils.getNetworkProtoResolver(),
TorNetworkNode node1 = new TorNetworkNode(port, TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), "", "", new ArrayList<String>()));
node1.start(new SetupListener() {
@Override
Expand All @@ -81,8 +80,7 @@ public void onRequestCustomBridges() {

latch = new CountDownLatch(1);
int port2 = 9002;
TorNetworkNode node2 = new TorNetworkNode(port2, new File("torNode_" + port2),
TestUtils.getNetworkProtoResolver(),
TorNetworkNode node2 = new TorNetworkNode(port2, TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), "", "", new ArrayList<String>()));
node2.start(new SetupListener() {
@Override
Expand Down Expand Up @@ -140,8 +138,7 @@ public void onFailure(@NotNull Throwable throwable) {
public void testTorNodeAfterBothReady() throws InterruptedException, IOException {
latch = new CountDownLatch(2);
int port = 9001;
TorNetworkNode node1 = new TorNetworkNode(port, new File("torNode_" + port),
TestUtils.getNetworkProtoResolver(),
TorNetworkNode node1 = new TorNetworkNode(port, TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), "", "", new ArrayList<String>()));
node1.start(new SetupListener() {
@Override
Expand All @@ -167,8 +164,7 @@ public void onRequestCustomBridges() {
});

int port2 = 9002;
TorNetworkNode node2 = new TorNetworkNode(port2, new File("torNode_" + port),
TestUtils.getNetworkProtoResolver(),
TorNetworkNode node2 = new TorNetworkNode(port2, TestUtils.getNetworkProtoResolver(),
new NewTor(new File("torNode_" + port), "", "", new ArrayList<String>()));
node2.start(new SetupListener() {
@Override
Expand Down

0 comments on commit 3a44b36

Please sign in to comment.