diff --git a/p2p/src/main/java/bisq/network/p2p/network/RunningTor.java b/p2p/src/main/java/bisq/network/p2p/network/RunningTor.java index 7b97b87e4b4..d142d2e02e3 100644 --- a/p2p/src/main/java/bisq/network/p2p/network/RunningTor.java +++ b/p2p/src/main/java/bisq/network/p2p/network/RunningTor.java @@ -19,12 +19,16 @@ import java.io.File; import java.io.IOException; + import java.util.Date; import org.berndpruenster.netlayer.tor.ExternalTor; import org.berndpruenster.netlayer.tor.Tor; import org.berndpruenster.netlayer.tor.TorCtlException; +import java.net.ConnectException; +import java.net.UnknownHostException; + import lombok.extern.slf4j.Slf4j; /** @@ -47,8 +51,12 @@ public class RunningTor extends TorMode { private final boolean useSafeCookieAuthentication; - public RunningTor(final File torDir, final String controlHost, final int controlPort, final String password, final File cookieFile, - final boolean useSafeCookieAuthentication) { + public RunningTor(final File torDir, + final String controlHost, + final int controlPort, + final String password, + final File cookieFile, + final boolean useSafeCookieAuthentication) { super(torDir); this.controlHost = controlHost; this.controlPort = controlPort; @@ -60,24 +68,47 @@ public RunningTor(final File torDir, final String controlHost, final int control @Override public Tor getTor() throws IOException, TorCtlException { long ts1 = new Date().getTime(); + boolean retry = true; + long twoMinutesInMilli = 1000 * 60 * 2; + + while (retry && ((new Date().getTime() - ts1) <= twoMinutesInMilli)) { + retry = false; + try { + log.info("Connecting to running tor"); + + Tor result; + if (!password.isEmpty()) + result = new ExternalTor(controlHost, controlPort, password); + else if (cookieFile != null && cookieFile.exists()) + result = new ExternalTor(controlHost, controlPort, cookieFile, useSafeCookieAuthentication); + else + result = new ExternalTor(controlHost, controlPort); + + boolean isTorBootstrapped = result.control.waitUntilBootstrapped(); + if (!isTorBootstrapped) { + log.error("Couldn't bootstrap Tor."); + } - log.info("Connecting to running tor"); + log.info( + "\n################################################################\n" + + "Connecting to Tor successful after {} ms. Start publishing hidden service.\n" + + "################################################################", + (new Date().getTime() - ts1)); // takes usually a few seconds - Tor result; - if (!password.isEmpty()) - result = new ExternalTor(controlHost, controlPort, password); - else if (cookieFile != null && cookieFile.exists()) - result = new ExternalTor(controlHost, controlPort, cookieFile, useSafeCookieAuthentication); - else - result = new ExternalTor(controlHost, controlPort); + return result; + } catch (Exception e) { + // netlayer throws UnknownHostException when tor docker container is not ready yet. + // netlayer throws ConnectException before tor container bind to control port. + if (e instanceof UnknownHostException || e instanceof ConnectException) { + log.warn("Couldn't connect to Tor control port. Retrying...", e); + retry = true; + } - log.info( - "\n################################################################\n" - + "Connecting to Tor successful after {} ms. Start publishing hidden service.\n" - + "################################################################", - (new Date().getTime() - ts1)); // takes usually a few seconds + log.error("Couldn't connect to Tor.", e); + } + } - return result; + return null; } @Override