mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
close connecting sockets and interrupt read thread on shutdown
This commit is contained in:
parent
a05fcba6d9
commit
0260a12663
10 changed files with 61 additions and 32 deletions
|
@ -944,6 +944,8 @@ public class AppController implements Initializable {
|
|||
if(AppServices.isConnected()) {
|
||||
return "Connected to " + Config.get().getServerDisplayName() + (currentBlockHeight != null ? " at height " + currentBlockHeight : "") +
|
||||
(Config.get().getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER ? "\nWarning! You are connected to a public server and sharing your transaction data with it.\nFor better privacy, consider using your own Bitcoin Core node or private Electrum server." : "");
|
||||
} else if(AppServices.isConnecting()) {
|
||||
return "Connecting...";
|
||||
}
|
||||
|
||||
return "Disconnected";
|
||||
|
|
|
@ -1139,10 +1139,12 @@ public class AppServices {
|
|||
@Subscribe
|
||||
public void requestDisconnect(RequestDisconnectEvent event) {
|
||||
onlineProperty.set(false);
|
||||
//Ensure services don't try to reconnect
|
||||
connectionService.cancel();
|
||||
ratesService.cancel();
|
||||
versionCheckService.cancel();
|
||||
//Ensure services don't try to reconnect later
|
||||
Platform.runLater(() -> {
|
||||
connectionService.cancel();
|
||||
ratesService.cancel();
|
||||
versionCheckService.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
|
|
@ -1063,6 +1063,7 @@ public class ElectrumServer {
|
|||
private final ReentrantLock bwtStartLock = new ReentrantLock();
|
||||
private final Condition bwtStartCondition = bwtStartLock.newCondition();
|
||||
private Throwable bwtStartException;
|
||||
private boolean shutdown;
|
||||
|
||||
public ConnectionService() {
|
||||
this(true);
|
||||
|
@ -1195,7 +1196,7 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
public boolean isConnecting() {
|
||||
return isRunning() && Config.get().getServerType() == ServerType.BITCOIN_CORE && bwt.isRunning() && !bwt.isReady();
|
||||
return isRunning() && firstCall && (Config.get().getServerType() != ServerType.BITCOIN_CORE || (bwt.isRunning() && !bwt.isReady()));
|
||||
}
|
||||
|
||||
public boolean isConnectionRunning() {
|
||||
|
@ -1203,7 +1204,11 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return isRunning() && (Config.get().getServerType() != ServerType.BITCOIN_CORE || (bwt.isRunning() && bwt.isReady()));
|
||||
return isRunning() && !firstCall && (Config.get().getServerType() != ServerType.BITCOIN_CORE || (bwt.isRunning() && bwt.isReady()));
|
||||
}
|
||||
|
||||
public boolean isShutdown() {
|
||||
return shutdown;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1219,6 +1224,11 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
private void shutdown() {
|
||||
shutdown = true;
|
||||
if(reader != null && reader.isAlive()) {
|
||||
reader.interrupt();
|
||||
}
|
||||
|
||||
if(Config.get().getServerType() == ServerType.BITCOIN_CORE && bwt.isRunning()) {
|
||||
Bwt.DisconnectionService disconnectionService = bwt.getDisconnectionService();
|
||||
disconnectionService.setOnSucceeded(workerStateEvent -> {
|
||||
|
|
|
@ -29,13 +29,11 @@ public class ProxyTcpOverTlsTransport extends TcpOverTlsTransport {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Socket createSocket() throws IOException {
|
||||
protected void createSocket() throws IOException {
|
||||
InetSocketAddress proxyAddr = new InetSocketAddress(proxy.getHost(), proxy.getPortOrDefault(DEFAULT_PROXY_PORT));
|
||||
Socket underlying = new Socket(new Proxy(Proxy.Type.SOCKS, proxyAddr));
|
||||
underlying.connect(new InetSocketAddress(server.getHost(), server.getPortOrDefault(DEFAULT_PORT)));
|
||||
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(underlying, proxy.getHost(), proxy.getPortOrDefault(DEFAULT_PROXY_PORT), true);
|
||||
startHandshake(sslSocket);
|
||||
|
||||
return sslSocket;
|
||||
socket = new Socket(new Proxy(Proxy.Type.SOCKS, proxyAddr));
|
||||
socket.connect(new InetSocketAddress(server.getHost(), server.getPortOrDefault(DEFAULT_PORT)));
|
||||
socket = sslSocketFactory.createSocket(socket, proxy.getHost(), proxy.getPortOrDefault(DEFAULT_PROXY_PORT), true);
|
||||
startHandshake((SSLSocket)socket);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import javax.net.ssl.*;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.Certificate;
|
||||
|
@ -86,10 +86,10 @@ public class TcpOverTlsTransport extends TcpTransport {
|
|||
return trustManagerFactory.getTrustManagers();
|
||||
}
|
||||
|
||||
protected Socket createSocket() throws IOException {
|
||||
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(server.getHost(), server.getPortOrDefault(DEFAULT_PORT));
|
||||
startHandshake(sslSocket);
|
||||
return sslSocket;
|
||||
protected void createSocket() throws IOException {
|
||||
socket = sslSocketFactory.createSocket();
|
||||
socket.connect(new InetSocketAddress(server.getHost(), server.getPortOrDefault(DEFAULT_PORT)));
|
||||
startHandshake((SSLSocket)socket);
|
||||
}
|
||||
|
||||
protected void startHandshake(SSLSocket sslSocket) throws IOException {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.slf4j.LoggerFactory;
|
|||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import java.io.*;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -36,7 +37,7 @@ public class TcpTransport implements CloseableTransport, TimeoutCounter {
|
|||
protected final SocketFactory socketFactory;
|
||||
protected final int[] readTimeouts;
|
||||
|
||||
private Socket socket;
|
||||
protected Socket socket;
|
||||
|
||||
private String response;
|
||||
|
||||
|
@ -231,7 +232,7 @@ public class TcpTransport implements CloseableTransport, TimeoutCounter {
|
|||
|
||||
public void connect() throws ServerException {
|
||||
try {
|
||||
socket = createSocket();
|
||||
createSocket();
|
||||
log.debug("Created " + socket);
|
||||
socket.setSoTimeout(SOCKET_READ_TIMEOUT_MILLIS);
|
||||
running = true;
|
||||
|
@ -250,8 +251,9 @@ public class TcpTransport implements CloseableTransport, TimeoutCounter {
|
|||
return socket != null && running && !closed;
|
||||
}
|
||||
|
||||
protected Socket createSocket() throws IOException {
|
||||
return socketFactory.createSocket(server.getHost(), server.getPortOrDefault(DEFAULT_PORT));
|
||||
protected void createSocket() throws IOException {
|
||||
socket = socketFactory.createSocket();
|
||||
socket.connect(new InetSocketAddress(server.getHost(), server.getPortOrDefault(DEFAULT_PORT)));
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
|
|
|
@ -26,9 +26,10 @@ public class TorTcpOverTlsTransport extends TcpOverTlsTransport {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Socket createSocket() throws IOException {
|
||||
protected void createSocket() throws IOException {
|
||||
TorTcpTransport torTcpTransport = new TorTcpTransport(server);
|
||||
Socket socket = torTcpTransport.createSocket();
|
||||
torTcpTransport.createSocket();
|
||||
socket = torTcpTransport.socket;
|
||||
|
||||
try {
|
||||
Field socketField = socket.getClass().getDeclaredField("socket");
|
||||
|
@ -41,9 +42,7 @@ public class TorTcpOverTlsTransport extends TcpOverTlsTransport {
|
|||
log.error("Could not set socket connected status", e);
|
||||
}
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, server.getHost(), server.getPortOrDefault(DEFAULT_PORT), true);
|
||||
startHandshake(sslSocket);
|
||||
|
||||
return sslSocket;
|
||||
socket = sslSocketFactory.createSocket(socket, server.getHost(), server.getPortOrDefault(DEFAULT_PORT), true);
|
||||
startHandshake((SSLSocket)socket);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ public class TorTcpTransport extends TcpTransport {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Socket createSocket() throws IOException {
|
||||
protected void createSocket() throws IOException {
|
||||
if(!AppServices.isTorRunning()) {
|
||||
throw new IllegalStateException("Can't create Tor socket, Tor is not running");
|
||||
}
|
||||
|
||||
return new TorSocket(server.getHost(), server.getPort(), "sparrow");
|
||||
socket = new TorSocket(server.getHost(), server.getPort(), "sparrow");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,6 +175,9 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
EventManager.get().register(this);
|
||||
getMasterController().closingProperty().addListener((observable, oldValue, newValue) -> {
|
||||
EventManager.get().unregister(this);
|
||||
if(connectionService != null && connectionService.isRunning()) {
|
||||
connectionService.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
Platform.runLater(this::setupValidation);
|
||||
|
@ -360,7 +363,7 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
|
||||
boolean isConnected = AppServices.isConnecting() || AppServices.isConnected();
|
||||
|
||||
if(AppServices.isConnecting()) {
|
||||
if(Config.get().getServerType() == ServerType.BITCOIN_CORE && AppServices.isConnecting()) {
|
||||
testResults.appendText("Connecting to server, please wait...");
|
||||
}
|
||||
|
||||
|
@ -380,7 +383,7 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
|
||||
editConnection.managedProperty().bind(editConnection.visibleProperty());
|
||||
editConnection.setVisible(isConnected);
|
||||
editConnection.setDisable(AppServices.isConnecting());
|
||||
editConnection.setDisable(Config.get().getServerType() == ServerType.BITCOIN_CORE && AppServices.isConnecting());
|
||||
editConnection.setOnAction(event -> {
|
||||
EventManager.get().post(new RequestDisconnectEvent());
|
||||
setFieldsEditable(true);
|
||||
|
@ -536,6 +539,11 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
});
|
||||
connectionService.setOnFailed(workerStateEvent -> {
|
||||
EventManager.get().unregister(connectionService);
|
||||
if(connectionService.isShutdown()) {
|
||||
connectionService.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
showConnectionFailure(workerStateEvent.getSource().getException());
|
||||
connectionService.cancel();
|
||||
|
||||
|
|
|
@ -95,6 +95,9 @@ public class ServerTestDialog extends DialogWindow {
|
|||
close();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
if(connectionService != null && connectionService.isRunning()) {
|
||||
connectionService.cancel();
|
||||
}
|
||||
if(Config.get().getMode() == Mode.ONLINE && !(AppServices.isConnecting() || AppServices.isConnected())) {
|
||||
EventManager.get().post(new RequestConnectEvent());
|
||||
}
|
||||
|
@ -145,6 +148,11 @@ public class ServerTestDialog extends DialogWindow {
|
|||
});
|
||||
connectionService.setOnFailed(workerStateEvent -> {
|
||||
EventManager.get().unregister(connectionService);
|
||||
if(connectionService.isShutdown()) {
|
||||
connectionService.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
showConnectionFailure(workerStateEvent.getSource().getException());
|
||||
connectionService.cancel();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue