Merge pull request #6147 from jmacxx/add_inbound_connectivity_test

Add inbound Tor connectivity test
This commit is contained in:
Christoph Atteneder 2022-04-13 10:56:31 +02:00 committed by GitHub
commit 82cae5a87d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 2 deletions

View file

@ -22,6 +22,11 @@ import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.SendMailboxMessageListener;
import bisq.network.p2p.mailbox.MailboxMessageService;
import bisq.network.p2p.network.Connection;
import bisq.network.p2p.network.MessageListener;
import bisq.network.p2p.network.NetworkNode;
import bisq.network.p2p.peers.keepalive.messages.Ping;
import bisq.network.p2p.peers.keepalive.messages.Pong;
import bisq.common.app.DevEnv;
import bisq.common.config.Config;
@ -36,6 +41,10 @@ import javax.inject.Inject;
import javax.inject.Named;
import com.google.common.base.Charsets;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
@ -45,16 +54,20 @@ import java.security.SignatureException;
import java.math.BigInteger;
import java.util.Random;
import java.util.UUID;
import java.util.function.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import static org.bitcoinj.core.Utils.HEX;
public class PrivateNotificationManager {
public class PrivateNotificationManager implements MessageListener {
private static final Logger log = LoggerFactory.getLogger(PrivateNotificationManager.class);
private final P2PService p2PService;
@ -69,6 +82,8 @@ public class PrivateNotificationManager {
@Nullable
private PrivateNotificationMessage privateNotificationMessage;
private final NetworkNode networkNode;
private Consumer<String> pingResponseHandler = null;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialization
@ -76,11 +91,13 @@ public class PrivateNotificationManager {
@Inject
public PrivateNotificationManager(P2PService p2PService,
NetworkNode networkNode,
MailboxMessageService mailboxMessageService,
KeyRing keyRing,
@Named(Config.IGNORE_DEV_MSG) boolean ignoreDevMsg,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
this.p2PService = p2PService;
this.networkNode = networkNode;
this.mailboxMessageService = mailboxMessageService;
this.keyRing = keyRing;
@ -173,5 +190,38 @@ public class PrivateNotificationManager {
}
}
public void sendPing(NodeAddress peersNodeAddress, Consumer<String> resultHandler) {
Ping ping = new Ping(new Random().nextInt(), 0);
log.info("Send Ping to peer {}, nonce={}", peersNodeAddress, ping.getNonce());
SettableFuture<Connection> future = networkNode.sendMessage(peersNodeAddress, ping);
Futures.addCallback(future, new FutureCallback<>() {
@Override
public void onSuccess(Connection connection) {
connection.addMessageListener(PrivateNotificationManager.this);
pingResponseHandler = resultHandler;
}
@Override
public void onFailure(@NotNull Throwable throwable) {
String errorMessage = "Sending ping to " + peersNodeAddress.getHostNameForDisplay() +
" failed. That is expected if the peer is offline.\n\tping=" + ping +
".\n\tException=" + throwable.getMessage();
log.info(errorMessage);
resultHandler.accept(errorMessage);
}
}, MoreExecutors.directExecutor());
}
@Override
public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if (networkEnvelope instanceof Pong) {
Pong pong = (Pong) networkEnvelope;
String key = connection.getPeersNodeAddressOptional().get().getFullAddress();
log.info("Received Pong! {} from {}", pong.toString(), key);
connection.removeMessageListener(this);
if (pingResponseHandler != null) {
pingResponseHandler.accept("SUCCESS");
}
}
}
}

View file

@ -94,6 +94,7 @@ public class BisqHeadlessApp implements HeadlessApp {
bisqSetup.setShowPopupIfInvalidBtcConfigHandler(() -> log.error("onShowPopupIfInvalidBtcConfigHandler"));
bisqSetup.setRevolutAccountsUpdateHandler(revolutAccountList -> log.info("setRevolutAccountsUpdateHandler: revolutAccountList={}", revolutAccountList));
bisqSetup.setQubesOSInfoHandler(() -> log.info("setQubesOSInfoHandler"));
bisqSetup.setFirewallIssueHandler(() -> log.info("setFirewallIssueHandler"));
bisqSetup.setDownGradePreventionHandler(lastVersion -> log.info("Downgrade from version {} to version {} is not supported",
lastVersion, Version.VERSION));
bisqSetup.setDaoRequiresRestartHandler(() -> {

View file

@ -22,6 +22,7 @@ import bisq.core.account.sign.SignedWitnessStorageService;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.Alert;
import bisq.core.alert.AlertManager;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.alert.PrivateNotificationPayload;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.nodes.LocalBitcoinNode;
@ -49,6 +50,7 @@ import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter;
import bisq.network.Socks5ProxyProvider;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.network.utils.Utils;
@ -132,6 +134,7 @@ public class BisqSetup {
private final WalletsSetup walletsSetup;
private final BtcWalletService btcWalletService;
private final P2PService p2PService;
private final PrivateNotificationManager privateNotificationManager;
private final SignedWitnessStorageService signedWitnessStorageService;
private final TradeManager tradeManager;
private final OpenOfferManager openOfferManager;
@ -194,6 +197,9 @@ public class BisqSetup {
private Runnable qubesOSInfoHandler;
@Setter
@Nullable
private Runnable firewallIssueHandler;
@Setter
@Nullable
private Runnable daoRequiresRestartHandler;
@Setter
@Nullable
@ -219,6 +225,7 @@ public class BisqSetup {
WalletsSetup walletsSetup,
BtcWalletService btcWalletService,
P2PService p2PService,
PrivateNotificationManager privateNotificationManager,
SignedWitnessStorageService signedWitnessStorageService,
TradeManager tradeManager,
OpenOfferManager openOfferManager,
@ -242,6 +249,7 @@ public class BisqSetup {
this.walletsSetup = walletsSetup;
this.btcWalletService = btcWalletService;
this.p2PService = p2PService;
this.privateNotificationManager = privateNotificationManager;
this.signedWitnessStorageService = signedWitnessStorageService;
this.tradeManager = tradeManager;
this.openOfferManager = openOfferManager;
@ -328,6 +336,7 @@ public class BisqSetup {
maybeShowLocalhostRunningInfo();
maybeShowAccountSigningStateInfo();
maybeShowTorAddressUpgradeInformation();
checkTorFirewall();
}
@ -650,6 +659,24 @@ public class BisqSetup {
}
}
/**
* If Bisq cannot connect to its own onion address through Tor, display
* an informative message to let the user know to configure their firewall else
* their offers will not be reachable.
*/
private void checkTorFirewall() {
NodeAddress onionAddress = p2PService.getNetworkNode().nodeAddressProperty().get();
if (onionAddress == null || !onionAddress.getFullAddress().contains("onion")) {
return;
}
privateNotificationManager.sendPing(onionAddress, stringResult -> {
log.warn(stringResult);
if (stringResult.contains("failed")) {
firewallIssueHandler.run();
}
});
}
private void maybeShowSecurityRecommendation() {
String key = "remindPasswordAndBackup";
user.getPaymentAccountsAsObservable().addListener((SetChangeListener<PaymentAccount>) change -> {

View file

@ -3079,6 +3079,9 @@ popup.info.shutDownWithOpenOffers=Bisq is being shut down, but there are open of
(i.e., make sure it doesn't go into standby mode...monitor standby is not a problem).
popup.info.qubesOSSetupInfo=It appears you are running Bisq on Qubes OS. \n\n\
Please make sure your Bisq qube is setup according to our Setup Guide at [HYPERLINK:https://bisq.wiki/Running_Bisq_on_Qubes].
popup.info.firewallSetupInfo=It appears this machine blocks incoming Tor connections. \
This can happen in VM environments such as Qubes/VirtualBox/Whonix. \n\n\
Please set up your environment to accept incoming Tor connections, otherwise no-one will be able to take your offers.
popup.warn.downGradePrevention=Downgrade from version {0} to version {1} is not supported. Please use the latest Bisq version.
popup.warn.daoRequiresRestart=There was a problem with synchronizing the DAO state. You have to restart the application to fix the issue.

View file

@ -479,6 +479,15 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
.show();
}
});
bisqSetup.setFirewallIssueHandler(() -> {
String key = "firewallSetupInfo";
if (preferences.showAgain(key)) {
new Popup().information(Res.get("popup.info.firewallSetupInfo"))
.closeButtonText(Res.get("shared.iUnderstand"))
.dontShowAgainId(key)
.show();
}
});
bisqSetup.setDownGradePreventionHandler(lastVersion -> {
new Popup().warning(Res.get("popup.warn.downGradePrevention", lastVersion, Version.VERSION))

View file

@ -127,7 +127,7 @@ public abstract class NetworkNode implements MessageListener {
Thread.currentThread().setName("NetworkNode:SendMessage-to-" + peersNodeAddress.getFullAddress());
if (peersNodeAddress.equals(getNodeAddress())) {
throw new ConnectException("We do not send a message to ourselves");
log.warn("We are sending a message to ourselves");
}
OutboundConnection outboundConnection = null;