diff --git a/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransport.java b/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransport.java index 286325fff0..3b0d4193fe 100644 --- a/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransport.java +++ b/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransport.java @@ -83,4 +83,13 @@ public CompletableFuture shutdown() { public Optional
getServerAddress(String serverId) { return Optional.empty(); } + + @Override + public boolean isAddressAvailable(Address address) { + try (Socket ignored = getSocket(address)) { + return true; + } catch (IOException e) { + return false; + } + } } diff --git a/network/src/main/java/bisq/network/p2p/node/transport/I2PTransport.java b/network/src/main/java/bisq/network/p2p/node/transport/I2PTransport.java index 54bbb43595..f248ba2c4d 100644 --- a/network/src/main/java/bisq/network/p2p/node/transport/I2PTransport.java +++ b/network/src/main/java/bisq/network/p2p/node/transport/I2PTransport.java @@ -175,6 +175,11 @@ public Socket getSocket(Address address) throws IOException { } } + @Override + public boolean isAddressAvailable(Address address) { + throw new UnsupportedOperationException("isAddressAvailable needs to be implemented for I2P."); + } + @Override public CompletableFuture shutdown() { initializeCalled = false; diff --git a/network/src/main/java/bisq/network/p2p/node/transport/TorTransport.java b/network/src/main/java/bisq/network/p2p/node/transport/TorTransport.java index 6e2533e461..153c9e1611 100644 --- a/network/src/main/java/bisq/network/p2p/node/transport/TorTransport.java +++ b/network/src/main/java/bisq/network/p2p/node/transport/TorTransport.java @@ -90,6 +90,11 @@ public Socket getSocket(Address address) throws IOException { return socket; } + @Override + public boolean isAddressAvailable(Address address) { + return tor.isHiddenServiceAvailable(address.getHost()); + } + public Optional getSocksProxy() throws IOException { return Optional.of(tor.getSocks5Proxy(null)); } diff --git a/network/src/main/java/bisq/network/p2p/node/transport/Transport.java b/network/src/main/java/bisq/network/p2p/node/transport/Transport.java index 3f40bfb823..2aee3d028b 100644 --- a/network/src/main/java/bisq/network/p2p/node/transport/Transport.java +++ b/network/src/main/java/bisq/network/p2p/node/transport/Transport.java @@ -83,5 +83,7 @@ default Optional getSocksProxy() throws IOException { Optional
getServerAddress(String serverId); + boolean isAddressAvailable(Address address); + CompletableFuture shutdown(); } diff --git a/tor/src/main/java/bisq/tor/Tor.java b/tor/src/main/java/bisq/tor/Tor.java index abcdfa3ff5..482a5dba5b 100644 --- a/tor/src/main/java/bisq/tor/Tor.java +++ b/tor/src/main/java/bisq/tor/Tor.java @@ -282,6 +282,10 @@ public Optional getHostName(String serverId) { return Optional.empty(); } + public boolean isHiddenServiceAvailable(String onionUrl) { + return torController.isHiddenServiceAvailable(onionUrl); + } + private void setState(State newState) { log.info("Set new state {}", newState); checkArgument(newState.ordinal() > state.get().ordinal(), diff --git a/tor/src/main/java/bisq/tor/TorController.java b/tor/src/main/java/bisq/tor/TorController.java index 40b434b14a..f65024f52c 100644 --- a/tor/src/main/java/bisq/tor/TorController.java +++ b/tor/src/main/java/bisq/tor/TorController.java @@ -119,6 +119,14 @@ int getProxyPort() throws IOException { return Integer.parseInt(port); } + boolean isHiddenServiceAvailable(String onionUrl) { + try { + return torControlConnection().isHSAvailable(onionUrl); + } catch (IOException e) { + return false; + } + } + TorControlConnection.CreateHiddenServiceResult createHiddenService(int hiddenServicePort, int localPort) throws IOException { assertState();