mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-24 15:35:34 -04:00
Add AuthenticationListener
This commit is contained in:
parent
2d518f9a16
commit
0d751eb561
7 changed files with 243 additions and 247 deletions
|
@ -15,6 +15,7 @@ import io.bitsquare.crypto.EncryptionService;
|
||||||
import io.bitsquare.crypto.SealedAndSignedMessage;
|
import io.bitsquare.crypto.SealedAndSignedMessage;
|
||||||
import io.bitsquare.p2p.messaging.*;
|
import io.bitsquare.p2p.messaging.*;
|
||||||
import io.bitsquare.p2p.network.*;
|
import io.bitsquare.p2p.network.*;
|
||||||
|
import io.bitsquare.p2p.peers.AuthenticationListener;
|
||||||
import io.bitsquare.p2p.peers.PeerGroup;
|
import io.bitsquare.p2p.peers.PeerGroup;
|
||||||
import io.bitsquare.p2p.peers.RequestDataManager;
|
import io.bitsquare.p2p.peers.RequestDataManager;
|
||||||
import io.bitsquare.p2p.seed.SeedNodesRepository;
|
import io.bitsquare.p2p.seed.SeedNodesRepository;
|
||||||
|
@ -41,17 +42,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class P2PService implements SetupListener, MessageListener, ConnectionListener, HashMapChangedListener {
|
public class P2PService implements SetupListener, MessageListener, ConnectionListener, HashMapChangedListener, AuthenticationListener {
|
||||||
private static final Logger log = LoggerFactory.getLogger(P2PService.class);
|
private static final Logger log = LoggerFactory.getLogger(P2PService.class);
|
||||||
|
|
||||||
private final SeedNodesRepository seedNodesRepository;
|
private final SeedNodesRepository seedNodesRepository;
|
||||||
private final int port;
|
private final int port;
|
||||||
private final File torDir;
|
private final File torDir;
|
||||||
private final boolean useLocalhost;
|
private final boolean useLocalhost;
|
||||||
@Nullable
|
private final Optional<EncryptionService> optionalEncryptionService;
|
||||||
private final EncryptionService encryptionService;
|
private final Optional<KeyRing> optionalKeyRing;
|
||||||
@Nullable
|
|
||||||
private final KeyRing keyRing;
|
|
||||||
|
|
||||||
// set in init
|
// set in init
|
||||||
private NetworkNode networkNode;
|
private NetworkNode networkNode;
|
||||||
|
@ -96,8 +95,9 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.torDir = torDir;
|
this.torDir = torDir;
|
||||||
this.useLocalhost = useLocalhost;
|
this.useLocalhost = useLocalhost;
|
||||||
this.encryptionService = encryptionService;
|
|
||||||
this.keyRing = keyRing;
|
optionalEncryptionService = encryptionService == null ? Optional.empty() : Optional.of(encryptionService);
|
||||||
|
optionalKeyRing = keyRing == null ? Optional.empty() : Optional.of(keyRing);
|
||||||
|
|
||||||
dbStorage = new Storage<>(storageDir);
|
dbStorage = new Storage<>(storageDir);
|
||||||
|
|
||||||
|
@ -131,6 +131,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
|
|
||||||
// peer group
|
// peer group
|
||||||
peerGroup = new PeerGroup(networkNode);
|
peerGroup = new PeerGroup(networkNode);
|
||||||
|
peerGroup.addAuthenticationListener(this);
|
||||||
if (useLocalhost)
|
if (useLocalhost)
|
||||||
PeerGroup.setSimulateAuthTorNode(200);
|
PeerGroup.setSimulateAuthTorNode(200);
|
||||||
|
|
||||||
|
@ -138,7 +139,23 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
dataStorage = new P2PDataStorage(peerGroup, storageDir);
|
dataStorage = new P2PDataStorage(peerGroup, storageDir);
|
||||||
dataStorage.addHashMapChangedListener(this);
|
dataStorage.addHashMapChangedListener(this);
|
||||||
|
|
||||||
|
// Request initial data manager
|
||||||
|
requestDataManager = new RequestDataManager(networkNode, dataStorage, new RequestDataManager.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onNoSeedNodeAvailable() {
|
||||||
|
p2pServiceListeners.stream().forEach(e -> e.onNoSeedNodeAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataReceived(Address seedNode) {
|
||||||
|
connectedSeedNode = seedNode;
|
||||||
|
requestingDataCompleted.set(true);
|
||||||
|
p2pServiceListeners.stream().forEach(e -> e.onRequestingDataCompleted());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
peerGroup.addAuthenticationListener(requestDataManager);
|
||||||
|
|
||||||
|
// Test multiple states to check when we are ready for authenticateSeedNode
|
||||||
readyForAuthentication = EasyBind.combine(hiddenServicePublished, requestingDataCompleted, firstPeerAuthenticated,
|
readyForAuthentication = EasyBind.combine(hiddenServicePublished, requestingDataCompleted, firstPeerAuthenticated,
|
||||||
(hiddenServicePublished, requestingDataCompleted, firstPeerAuthenticated)
|
(hiddenServicePublished, requestingDataCompleted, firstPeerAuthenticated)
|
||||||
-> hiddenServicePublished && requestingDataCompleted && !firstPeerAuthenticated);
|
-> hiddenServicePublished && requestingDataCompleted && !firstPeerAuthenticated);
|
||||||
|
@ -157,7 +174,10 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
|
|
||||||
public void startAsSeedNode(Address mySeedNodeAddress, @Nullable P2PServiceListener listener) {
|
public void startAsSeedNode(Address mySeedNodeAddress, @Nullable P2PServiceListener listener) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
|
|
||||||
|
// we remove ourselves from the list of seed nodes
|
||||||
seedNodeAddresses.remove(mySeedNodeAddress);
|
seedNodeAddresses.remove(mySeedNodeAddress);
|
||||||
|
|
||||||
start(listener);
|
start(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,33 +219,30 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap sequence:
|
||||||
|
* <p>
|
||||||
|
* Variant 1 (normal expected mode):
|
||||||
|
* onTorNodeReady -> requestDataManager.requestData()
|
||||||
|
* RequestDataManager.Listener.onDataReceived && onHiddenServicePublished -> authenticateSeedNode()
|
||||||
|
* RequestDataManager.onPeerAddressAuthenticated -> RequestDataManager.requestDataFromAuthenticatedSeedNode()
|
||||||
|
* <p>
|
||||||
|
* Variant 2 (no seed node available):
|
||||||
|
* onTorNodeReady -> requestDataManager.requestData
|
||||||
|
* RequestDataManager.Listener.onNoSeedNodeAvailable && onHiddenServicePublished -> retry after 20-30 until
|
||||||
|
* seed node is available and data can be retrieved
|
||||||
|
* RequestDataManager.Listener.onDataReceived && onHiddenServicePublished -> authenticateSeedNode()
|
||||||
|
* RequestDataManager.onPeerAddressAuthenticated -> RequestDataManager.requestDataFromAuthenticatedSeedNode()
|
||||||
|
*/
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// SetupListener implementation
|
// SetupListener implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTorNodeReady() {
|
public void onTorNodeReady() {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onTorNodeReady());
|
|
||||||
|
|
||||||
// 1. Step: As soon we have the tor node ready (hidden service still not available) we request the
|
|
||||||
// data set from a random seed node.
|
|
||||||
requestDataManager = new RequestDataManager(networkNode, dataStorage, new RequestDataManager.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onNoSeedNodeAvailable() {
|
|
||||||
// 2b. or 3b Step: If no seed node available we keep trying again after a random pause
|
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onNoSeedNodeAvailable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDataReceived(Address seedNode) {
|
|
||||||
// 2a. or 3a Step: We received initial data set
|
|
||||||
connectedSeedNode = seedNode;
|
|
||||||
requestingDataCompleted.set(true);
|
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onRequestingDataCompleted());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
requestDataManager.requestData(seedNodeAddresses);
|
requestDataManager.requestData(seedNodeAddresses);
|
||||||
|
p2pServiceListeners.stream().forEach(e -> e.onTorNodeReady());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -240,7 +257,6 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
dbStorage.queueUpForSave(myOnionAddress);
|
dbStorage.queueUpForSave(myOnionAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. (or 2.). Step: Hidden service is published
|
|
||||||
hiddenServicePublished.set(true);
|
hiddenServicePublished.set(true);
|
||||||
|
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onHiddenServicePublished());
|
p2pServiceListeners.stream().forEach(e -> e.onHiddenServicePublished());
|
||||||
|
@ -252,14 +268,53 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onSetupFailed(throwable));
|
p2pServiceListeners.stream().forEach(e -> e.onSetupFailed(throwable));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Step: hiddenServicePublished and requestingDataCompleted. We start authenticate to the connected seed node.
|
|
||||||
private void authenticateSeedNode() {
|
private void authenticateSeedNode() {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
checkNotNull(connectedSeedNode != null, "connectedSeedNode must not be null");
|
checkNotNull(connectedSeedNode != null, "connectedSeedNode must not be null");
|
||||||
peerGroup.authenticateSeedNode(connectedSeedNode);
|
peerGroup.authenticateSeedNode(connectedSeedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Step: in RequestDataManager (after authentication to first seed node we request again the data)
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ConnectionListener implementation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnection(Connection connection) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect(Reason reason, Connection connection) {
|
||||||
|
Log.traceCall();
|
||||||
|
if (connection.isAuthenticated())
|
||||||
|
authenticatedPeerAddresses.remove(connection.getPeerAddress());
|
||||||
|
|
||||||
|
numAuthenticatedPeers.set(authenticatedPeerAddresses.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable throwable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// AuthenticationListener implementation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
||||||
|
Log.traceCall();
|
||||||
|
checkArgument(peerAddress.equals(connection.getPeerAddress()),
|
||||||
|
"peerAddress must match connection.getPeerAddress()");
|
||||||
|
authenticatedPeerAddresses.add(peerAddress);
|
||||||
|
|
||||||
|
if (!firstPeerAuthenticated.get()) {
|
||||||
|
firstPeerAuthenticated.set(true);
|
||||||
|
p2pServiceListeners.stream().forEach(e -> e.onFirstPeerAuthenticated());
|
||||||
|
}
|
||||||
|
|
||||||
|
numAuthenticatedPeers.set(authenticatedPeerAddresses.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -271,11 +326,11 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
if (message instanceof SealedAndSignedMessage) {
|
if (message instanceof SealedAndSignedMessage) {
|
||||||
Log.traceCall(message.toString());
|
Log.traceCall(message.toString());
|
||||||
// Seed nodes don't have set the encryptionService
|
// Seed nodes don't have set the encryptionService
|
||||||
if (encryptionService != null) {
|
if (optionalEncryptionService.isPresent()) {
|
||||||
try {
|
try {
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = (SealedAndSignedMessage) message;
|
SealedAndSignedMessage sealedAndSignedMessage = (SealedAndSignedMessage) message;
|
||||||
if (verifyAddressPrefixHash(sealedAndSignedMessage)) {
|
if (verifyAddressPrefixHash(sealedAndSignedMessage)) {
|
||||||
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(
|
DecryptedMsgWithPubKey decryptedMsgWithPubKey = optionalEncryptionService.get().decryptAndVerify(
|
||||||
sealedAndSignedMessage.sealedAndSigned);
|
sealedAndSignedMessage.sealedAndSigned);
|
||||||
|
|
||||||
// We set connectionType to that connection to avoid that is get closed when
|
// We set connectionType to that connection to avoid that is get closed when
|
||||||
|
@ -298,46 +353,10 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ConnectionListener implementation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConnection(Connection connection) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
|
||||||
Log.traceCall();
|
|
||||||
checkArgument(peerAddress.equals(connection.getPeerAddress()),
|
|
||||||
"peerAddress must match connection.getPeerAddress()");
|
|
||||||
authenticatedPeerAddresses.add(peerAddress);
|
|
||||||
|
|
||||||
if (!firstPeerAuthenticated.get()) {
|
|
||||||
firstPeerAuthenticated.set(true);
|
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onFirstPeerAuthenticated());
|
|
||||||
}
|
|
||||||
|
|
||||||
numAuthenticatedPeers.set(authenticatedPeerAddresses.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisconnect(Reason reason, Connection connection) {
|
|
||||||
Log.traceCall();
|
|
||||||
if (connection.isAuthenticated())
|
|
||||||
authenticatedPeerAddresses.remove(connection.getPeerAddress());
|
|
||||||
|
|
||||||
numAuthenticatedPeers.set(authenticatedPeerAddresses.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable throwable) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// HashMapChangedListener implementation
|
// HashMapChangedListener implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdded(ProtectedData entry) {
|
public void onAdded(ProtectedData entry) {
|
||||||
if (entry instanceof ProtectedMailboxData)
|
if (entry instanceof ProtectedMailboxData)
|
||||||
|
@ -370,10 +389,10 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
private void doSendEncryptedMailMessage(Address peerAddress, PubKeyRing pubKeyRing, MailMessage message,
|
private void doSendEncryptedMailMessage(Address peerAddress, PubKeyRing pubKeyRing, MailMessage message,
|
||||||
SendMailMessageListener sendMailMessageListener) {
|
SendMailMessageListener sendMailMessageListener) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
if (encryptionService != null) {
|
checkArgument(optionalEncryptionService.isPresent(), "EncryptionService not set. Seems that is called on a seed node which must not happen.");
|
||||||
try {
|
try {
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
||||||
encryptionService.encryptAndSign(pubKeyRing, message), peerAddress.getAddressPrefixHash());
|
optionalEncryptionService.get().encryptAndSign(pubKeyRing, message), peerAddress.getAddressPrefixHash());
|
||||||
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, sealedAndSignedMessage);
|
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, sealedAndSignedMessage);
|
||||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -392,7 +411,6 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
sendMailMessageListener.onFault();
|
sendMailMessageListener.onFault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -400,7 +418,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void processProtectedMailboxData(ProtectedMailboxData mailboxData) {
|
private void processProtectedMailboxData(ProtectedMailboxData mailboxData) {
|
||||||
if (encryptionService != null) {
|
// Seed nodes don't have set the encryptionService
|
||||||
|
if (optionalEncryptionService.isPresent()) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
ExpirablePayload expirablePayload = mailboxData.expirablePayload;
|
ExpirablePayload expirablePayload = mailboxData.expirablePayload;
|
||||||
if (expirablePayload instanceof ExpirableMailboxPayload) {
|
if (expirablePayload instanceof ExpirableMailboxPayload) {
|
||||||
|
@ -408,7 +427,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = expirableMailboxPayload.sealedAndSignedMessage;
|
SealedAndSignedMessage sealedAndSignedMessage = expirableMailboxPayload.sealedAndSignedMessage;
|
||||||
if (verifyAddressPrefixHash(sealedAndSignedMessage)) {
|
if (verifyAddressPrefixHash(sealedAndSignedMessage)) {
|
||||||
try {
|
try {
|
||||||
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(
|
DecryptedMsgWithPubKey decryptedMsgWithPubKey = optionalEncryptionService.get().decryptAndVerify(
|
||||||
sealedAndSignedMessage.sealedAndSigned);
|
sealedAndSignedMessage.sealedAndSigned);
|
||||||
if (decryptedMsgWithPubKey.message instanceof MailboxMessage) {
|
if (decryptedMsgWithPubKey.message instanceof MailboxMessage) {
|
||||||
MailboxMessage mailboxMessage = (MailboxMessage) decryptedMsgWithPubKey.message;
|
MailboxMessage mailboxMessage = (MailboxMessage) decryptedMsgWithPubKey.message;
|
||||||
|
@ -439,7 +458,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
|
MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
checkNotNull(peerAddress, "PeerAddress must not be null (sendEncryptedMailboxMessage)");
|
checkNotNull(peerAddress, "PeerAddress must not be null (sendEncryptedMailboxMessage)");
|
||||||
checkArgument(!keyRing.getPubKeyRing().equals(peersPubKeyRing), "We got own keyring instead of that from peer");
|
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
|
||||||
|
checkArgument(!optionalKeyRing.get().getPubKeyRing().equals(peersPubKeyRing), "We got own keyring instead of that from peer");
|
||||||
checkAuthentication();
|
checkAuthentication();
|
||||||
|
|
||||||
if (authenticatedPeerAddresses.contains(peerAddress)) {
|
if (authenticatedPeerAddresses.contains(peerAddress)) {
|
||||||
|
@ -458,10 +478,11 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
private void trySendEncryptedMailboxMessage(Address peerAddress, PubKeyRing peersPubKeyRing,
|
private void trySendEncryptedMailboxMessage(Address peerAddress, PubKeyRing peersPubKeyRing,
|
||||||
MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
|
MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
if (encryptionService != null) {
|
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
|
||||||
|
checkArgument(optionalEncryptionService.isPresent(), "EncryptionService not set. Seems that is called on a seed node which must not happen.");
|
||||||
try {
|
try {
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
||||||
encryptionService.encryptAndSign(peersPubKeyRing, message), peerAddress.getAddressPrefixHash());
|
optionalEncryptionService.get().encryptAndSign(peersPubKeyRing, message), peerAddress.getAddressPrefixHash());
|
||||||
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, sealedAndSignedMessage);
|
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, sealedAndSignedMessage);
|
||||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -478,7 +499,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
log.trace("create MailboxEntry with peerAddress " + peerAddress);
|
log.trace("create MailboxEntry with peerAddress " + peerAddress);
|
||||||
PublicKey receiverStoragePublicKey = peersPubKeyRing.getSignaturePubKey();
|
PublicKey receiverStoragePublicKey = peersPubKeyRing.getSignaturePubKey();
|
||||||
addMailboxData(new ExpirableMailboxPayload(sealedAndSignedMessage,
|
addMailboxData(new ExpirableMailboxPayload(sealedAndSignedMessage,
|
||||||
keyRing.getSignatureKeyPair().getPublic(),
|
optionalKeyRing.get().getSignatureKeyPair().getPublic(),
|
||||||
receiverStoragePublicKey),
|
receiverStoragePublicKey),
|
||||||
receiverStoragePublicKey);
|
receiverStoragePublicKey);
|
||||||
sendMailboxMessageListener.onStoredInMailbox();
|
sendMailboxMessageListener.onStoredInMailbox();
|
||||||
|
@ -490,7 +511,52 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
sendMailboxMessageListener.onFault();
|
sendMailboxMessageListener.onFault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addMailboxData(ExpirableMailboxPayload expirableMailboxPayload, PublicKey receiversPublicKey) {
|
||||||
|
Log.traceCall();
|
||||||
|
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
|
||||||
|
checkAuthentication();
|
||||||
|
try {
|
||||||
|
ProtectedMailboxData protectedMailboxData = dataStorage.getMailboxDataWithSignedSeqNr(
|
||||||
|
expirableMailboxPayload,
|
||||||
|
optionalKeyRing.get().getSignatureKeyPair(),
|
||||||
|
receiversPublicKey);
|
||||||
|
dataStorage.add(protectedMailboxData, networkNode.getAddress());
|
||||||
|
} catch (CryptoException e) {
|
||||||
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeEntryFromMailbox(DecryptedMsgWithPubKey decryptedMsgWithPubKey) {
|
||||||
|
Log.traceCall();
|
||||||
|
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
|
||||||
|
checkAuthentication();
|
||||||
|
if (mailboxMap.containsKey(decryptedMsgWithPubKey)) {
|
||||||
|
ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMsgWithPubKey);
|
||||||
|
if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) {
|
||||||
|
ExpirableMailboxPayload expirableMailboxPayload = (ExpirableMailboxPayload) mailboxData.expirablePayload;
|
||||||
|
PublicKey receiversPubKey = mailboxData.receiversPubKey;
|
||||||
|
checkArgument(receiversPubKey.equals(optionalKeyRing.get().getSignatureKeyPair().getPublic()),
|
||||||
|
"receiversPubKey is not matching with our key. That must not happen.");
|
||||||
|
try {
|
||||||
|
ProtectedMailboxData protectedMailboxData = dataStorage.getMailboxDataWithSignedSeqNr(
|
||||||
|
expirableMailboxPayload,
|
||||||
|
optionalKeyRing.get().getSignatureKeyPair(),
|
||||||
|
receiversPubKey);
|
||||||
|
dataStorage.removeMailboxData(protectedMailboxData, networkNode.getAddress());
|
||||||
|
} catch (CryptoException e) {
|
||||||
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
mailboxMap.remove(decryptedMsgWithPubKey);
|
||||||
|
log.trace("Removed successfully decryptedMsgWithPubKey.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("decryptedMsgWithPubKey not found in mailboxMap. That should never happen." +
|
||||||
|
"\ndecryptedMsgWithPubKey={}\nmailboxMap={}", decryptedMsgWithPubKey, mailboxMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Data storage
|
// Data storage
|
||||||
|
@ -508,10 +574,10 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
|
|
||||||
private boolean doAddData(ExpirablePayload expirablePayload, boolean rePublish) {
|
private boolean doAddData(ExpirablePayload expirablePayload, boolean rePublish) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
|
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
|
||||||
checkAuthentication();
|
checkAuthentication();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ProtectedData protectedData = dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair());
|
ProtectedData protectedData = dataStorage.getDataWithSignedSeqNr(expirablePayload, optionalKeyRing.get().getSignatureKeyPair());
|
||||||
if (rePublish)
|
if (rePublish)
|
||||||
return dataStorage.rePublish(protectedData, networkNode.getAddress());
|
return dataStorage.rePublish(protectedData, networkNode.getAddress());
|
||||||
else
|
else
|
||||||
|
@ -522,27 +588,12 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMailboxData(ExpirableMailboxPayload expirableMailboxPayload, PublicKey receiversPublicKey) {
|
|
||||||
Log.traceCall();
|
|
||||||
checkAuthentication();
|
|
||||||
|
|
||||||
try {
|
|
||||||
ProtectedMailboxData protectedMailboxData = dataStorage.getMailboxDataWithSignedSeqNr(
|
|
||||||
expirableMailboxPayload,
|
|
||||||
keyRing.getSignatureKeyPair(),
|
|
||||||
receiversPublicKey);
|
|
||||||
dataStorage.add(protectedMailboxData, networkNode.getAddress());
|
|
||||||
} catch (CryptoException e) {
|
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeData(ExpirablePayload expirablePayload) {
|
public boolean removeData(ExpirablePayload expirablePayload) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
|
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
|
||||||
checkAuthentication();
|
checkAuthentication();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ProtectedData protectedData = dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair());
|
ProtectedData protectedData = dataStorage.getDataWithSignedSeqNr(expirablePayload, optionalKeyRing.get().getSignatureKeyPair());
|
||||||
return dataStorage.remove(protectedData, networkNode.getAddress());
|
return dataStorage.remove(protectedData, networkNode.getAddress());
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
|
@ -550,40 +601,6 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeEntryFromMailbox(DecryptedMsgWithPubKey decryptedMsgWithPubKey) {
|
|
||||||
Log.traceCall();
|
|
||||||
checkAuthentication();
|
|
||||||
|
|
||||||
if (mailboxMap.containsKey(decryptedMsgWithPubKey)) {
|
|
||||||
ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMsgWithPubKey);
|
|
||||||
if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) {
|
|
||||||
ExpirableMailboxPayload expirableMailboxPayload = (ExpirableMailboxPayload) mailboxData.expirablePayload;
|
|
||||||
PublicKey receiversPubKey = mailboxData.receiversPubKey;
|
|
||||||
checkArgument(receiversPubKey.equals(keyRing.getSignatureKeyPair().getPublic()),
|
|
||||||
"receiversPubKey is not matching with our key. That must not happen.");
|
|
||||||
try {
|
|
||||||
ProtectedMailboxData protectedMailboxData = dataStorage.getMailboxDataWithSignedSeqNr(
|
|
||||||
expirableMailboxPayload,
|
|
||||||
keyRing.getSignatureKeyPair(),
|
|
||||||
receiversPubKey);
|
|
||||||
dataStorage.removeMailboxData(protectedMailboxData, networkNode.getAddress());
|
|
||||||
} catch (CryptoException e) {
|
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mailboxMap.remove(decryptedMsgWithPubKey);
|
|
||||||
log.trace("Removed successfully decryptedMsgWithPubKey.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("decryptedMsgWithPubKey not found in mailboxMap. That should never happen." +
|
|
||||||
"\ndecryptedMsgWithPubKey={}\nmailboxMap={}", decryptedMsgWithPubKey, mailboxMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<ByteArray, ProtectedData> getDataMap() {
|
|
||||||
return dataStorage.getMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Listeners
|
// Listeners
|
||||||
|
@ -646,15 +663,15 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
return numAuthenticatedPeers;
|
return numAuthenticatedPeers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<ByteArray, ProtectedData> getDataMap() {
|
||||||
|
return dataStorage.getMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Private
|
// Private
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private HashSet<ProtectedData> getDataSet() {
|
|
||||||
return new HashSet<>(getDataMap().values());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean verifyAddressPrefixHash(SealedAndSignedMessage sealedAndSignedMessage) {
|
private boolean verifyAddressPrefixHash(SealedAndSignedMessage sealedAndSignedMessage) {
|
||||||
if (myOnionAddress != null) {
|
if (myOnionAddress != null) {
|
||||||
byte[] blurredAddressHash = myOnionAddress.getAddressPrefixHash();
|
byte[] blurredAddressHash = myOnionAddress.getAddressPrefixHash();
|
||||||
|
|
|
@ -120,8 +120,6 @@ public class Connection implements MessageListener {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
this.peerAddress = peerAddress;
|
this.peerAddress = peerAddress;
|
||||||
isAuthenticated = true;
|
isAuthenticated = true;
|
||||||
if (!stopped)
|
|
||||||
connectionListener.onPeerAddressAuthenticated(peerAddress, connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectionPriority(ConnectionPriority connectionPriority) {
|
public void setConnectionPriority(ConnectionPriority connectionPriority) {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package io.bitsquare.p2p.network;
|
package io.bitsquare.p2p.network;
|
||||||
|
|
||||||
|
|
||||||
import io.bitsquare.p2p.Address;
|
|
||||||
|
|
||||||
public interface ConnectionListener {
|
public interface ConnectionListener {
|
||||||
enum Reason {
|
enum Reason {
|
||||||
SOCKET_CLOSED,
|
SOCKET_CLOSED,
|
||||||
|
@ -15,8 +13,6 @@ public interface ConnectionListener {
|
||||||
|
|
||||||
void onConnection(Connection connection);
|
void onConnection(Connection connection);
|
||||||
|
|
||||||
void onPeerAddressAuthenticated(Address peerAddress, Connection connection);
|
|
||||||
|
|
||||||
void onDisconnect(Reason reason, Connection connection);
|
void onDisconnect(Reason reason, Connection connection);
|
||||||
|
|
||||||
void onError(Throwable throwable);
|
void onError(Throwable throwable);
|
||||||
|
|
|
@ -230,14 +230,6 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
|
||||||
connectionListeners.stream().forEach(e -> e.onConnection(connection));
|
connectionListeners.stream().forEach(e -> e.onConnection(connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
|
||||||
Log.traceCall();
|
|
||||||
log.trace("onAuthenticationComplete peerAddress/connection: " + peerAddress + " / " + connection);
|
|
||||||
|
|
||||||
connectionListeners.stream().forEach(e -> e.onPeerAddressAuthenticated(peerAddress, connection));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect(Reason reason, Connection connection) {
|
public void onDisconnect(Reason reason, Connection connection) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
|
@ -320,12 +312,6 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
|
||||||
NetworkNode.this.onConnection(connection);
|
NetworkNode.this.onConnection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
|
||||||
Log.traceCall();
|
|
||||||
NetworkNode.this.onPeerAddressAuthenticated(peerAddress, connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect(Reason reason, Connection connection) {
|
public void onDisconnect(Reason reason, Connection connection) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package io.bitsquare.p2p.peers;
|
||||||
|
|
||||||
|
import io.bitsquare.p2p.Address;
|
||||||
|
import io.bitsquare.p2p.network.Connection;
|
||||||
|
|
||||||
|
public interface AuthenticationListener {
|
||||||
|
void onPeerAddressAuthenticated(Address peerAddress, Connection connection);
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -40,19 +41,18 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
MAX_CONNECTIONS_LOW_PRIO = maxConnectionsLowPrio;
|
MAX_CONNECTIONS_LOW_PRIO = maxConnectionsLowPrio;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int PING_AFTER_CONNECTION_INACTIVITY = 30 * 1000;
|
private static final int INACTIVITY_PERIOD_BEFORE_PING = 30 * 1000;
|
||||||
private static final int MAX_REPORTED_PEERS = 1000;
|
private static final int MAX_REPORTED_PEERS = 1000;
|
||||||
|
|
||||||
private final NetworkNode networkNode;
|
private final NetworkNode networkNode;
|
||||||
private Set<Address> seedNodeAddresses;
|
private final CopyOnWriteArraySet<AuthenticationListener> authenticationListeners = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
private final Map<Address, Peer> authenticatedPeers = new HashMap<>();
|
private final Map<Address, Peer> authenticatedPeers = new HashMap<>();
|
||||||
private final Set<ReportedPeer> reportedPeers = new HashSet<>();
|
private final Set<ReportedPeer> reportedPeers = new HashSet<>();
|
||||||
private final Map<Address, AuthenticationHandshake> authenticationHandshakes = new HashMap<>();
|
private final Map<Address, AuthenticationHandshake> authenticationHandshakes = new HashMap<>();
|
||||||
|
private Timer sendPingTimer;
|
||||||
|
private Timer getPeersTimer;
|
||||||
|
|
||||||
private Timer sendPingTimer = new Timer();
|
private Set<Address> seedNodeAddresses;
|
||||||
private Timer getPeersTimer = new Timer();
|
|
||||||
|
|
||||||
private boolean shutDownInProgress;
|
private boolean shutDownInProgress;
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,10 +72,29 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
startGetPeersTimer();
|
startGetPeersTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSeedNodeAddresses(Set<Address> seedNodeAddresses) {
|
public void addAuthenticationListener(AuthenticationListener listener) {
|
||||||
this.seedNodeAddresses = seedNodeAddresses;
|
authenticationListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ConnectionListener implementation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnection(Connection connection) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect(Reason reason, Connection connection) {
|
||||||
|
log.debug("onDisconnect connection=" + connection + " / reason=" + reason);
|
||||||
|
removePeer(connection.getPeerAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable throwable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// MessageListener implementation
|
// MessageListener implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -89,33 +108,14 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ConnectionListener implementation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConnection(Connection connection) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisconnect(Reason reason, Connection connection) {
|
|
||||||
log.debug("onDisconnect connection=" + connection + " / reason=" + reason);
|
|
||||||
removePeer(connection.getPeerAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable throwable) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// API
|
// API
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void setSeedNodeAddresses(Set<Address> seedNodeAddresses) {
|
||||||
|
this.seedNodeAddresses = seedNodeAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
public void broadcast(DataBroadcastMessage message, @Nullable Address sender) {
|
public void broadcast(DataBroadcastMessage message, @Nullable Address sender) {
|
||||||
Log.traceCall("Sender " + sender + ". Message " + message.toString());
|
Log.traceCall("Sender " + sender + ". Message " + message.toString());
|
||||||
if (authenticatedPeers.values().size() > 0) {
|
if (authenticatedPeers.values().size() > 0) {
|
||||||
|
@ -442,6 +442,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
|
|
||||||
addAuthenticatedPeer(new Peer(connection));
|
addAuthenticatedPeer(new Peer(connection));
|
||||||
connection.setAuthenticated(peerAddress, connection);
|
connection.setAuthenticated(peerAddress, connection);
|
||||||
|
authenticationListeners.stream().forEach(e -> e.onPeerAddressAuthenticated(peerAddress, connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAuthenticatedPeer(Peer peer) {
|
private void addAuthenticatedPeer(Peer peer) {
|
||||||
|
@ -455,6 +456,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
printAuthenticatedPeers();
|
printAuthenticatedPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Maintenance
|
// Maintenance
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -542,7 +544,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
if (!connectedPeersList.isEmpty()) {
|
if (!connectedPeersList.isEmpty()) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
connectedPeersList.stream()
|
connectedPeersList.stream()
|
||||||
.filter(e -> (new Date().getTime() - e.connection.getLastActivityDate().getTime()) > PING_AFTER_CONNECTION_INACTIVITY)
|
.filter(e -> (new Date().getTime() - e.connection.getLastActivityDate().getTime()) > INACTIVITY_PERIOD_BEFORE_PING)
|
||||||
.forEach(e -> UserThread.runAfterRandomDelay(() -> {
|
.forEach(e -> UserThread.runAfterRandomDelay(() -> {
|
||||||
SettableFuture<Connection> future = networkNode.sendMessage(e.connection, new PingMessage(e.getPingNonce()));
|
SettableFuture<Connection> future = networkNode.sendMessage(e.connection, new PingMessage(e.getPingNonce()));
|
||||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.p2p.Address;
|
import io.bitsquare.p2p.Address;
|
||||||
import io.bitsquare.p2p.Message;
|
import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.network.Connection;
|
import io.bitsquare.p2p.network.Connection;
|
||||||
import io.bitsquare.p2p.network.ConnectionListener;
|
|
||||||
import io.bitsquare.p2p.network.MessageListener;
|
import io.bitsquare.p2p.network.MessageListener;
|
||||||
import io.bitsquare.p2p.network.NetworkNode;
|
import io.bitsquare.p2p.network.NetworkNode;
|
||||||
import io.bitsquare.p2p.storage.P2PDataStorage;
|
import io.bitsquare.p2p.storage.P2PDataStorage;
|
||||||
|
@ -25,7 +24,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
public class RequestDataManager implements MessageListener, ConnectionListener {
|
public class RequestDataManager implements MessageListener, AuthenticationListener {
|
||||||
private static final Logger log = LoggerFactory.getLogger(RequestDataManager.class);
|
private static final Logger log = LoggerFactory.getLogger(RequestDataManager.class);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -56,7 +55,6 @@ public class RequestDataManager implements MessageListener, ConnectionListener {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
|
||||||
networkNode.addMessageListener(this);
|
networkNode.addMessageListener(this);
|
||||||
networkNode.addConnectionListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -129,13 +127,11 @@ public class RequestDataManager implements MessageListener, ConnectionListener {
|
||||||
listener.onDataReceived(connectedSeedNodeAddress);
|
listener.onDataReceived(connectedSeedNodeAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ConnectionListener implementation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConnection(Connection connection) {
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
}
|
// AuthenticationListener implementation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
|
||||||
|
@ -143,13 +139,6 @@ public class RequestDataManager implements MessageListener, ConnectionListener {
|
||||||
requestDataFromAuthenticatedSeedNode(peerAddress, connection);
|
requestDataFromAuthenticatedSeedNode(peerAddress, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisconnect(Reason reason, Connection connection) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable throwable) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Step after authentication to first seed node we request again the data
|
// 5. Step after authentication to first seed node we request again the data
|
||||||
private void requestDataFromAuthenticatedSeedNode(Address peerAddress, Connection connection) {
|
private void requestDataFromAuthenticatedSeedNode(Address peerAddress, Connection connection) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue