mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-05 21:24:19 -04:00
Add blurred address hash for encrypted msg
This commit is contained in:
parent
3c3a148b57
commit
b827a9812d
9 changed files with 99 additions and 71 deletions
|
@ -5,15 +5,19 @@ import io.bitsquare.common.crypto.SealedAndSigned;
|
||||||
import io.bitsquare.p2p.Address;
|
import io.bitsquare.p2p.Address;
|
||||||
import io.bitsquare.p2p.messaging.MailboxMessage;
|
import io.bitsquare.p2p.messaging.MailboxMessage;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public final class SealedAndSignedMessage implements MailboxMessage {
|
public final class SealedAndSignedMessage implements MailboxMessage {
|
||||||
// That object is sent over the wire, so we need to take care of version compatibility.
|
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||||
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
|
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
|
||||||
|
|
||||||
private final int networkId = Version.NETWORK_ID;
|
private final int networkId = Version.NETWORK_ID;
|
||||||
public final SealedAndSigned sealedAndSigned;
|
public final SealedAndSigned sealedAndSigned;
|
||||||
|
public final byte[] blurredAddressHash;
|
||||||
|
|
||||||
public SealedAndSignedMessage(SealedAndSigned sealedAndSigned) {
|
public SealedAndSignedMessage(SealedAndSigned sealedAndSigned, byte[] blurredAddressHash) {
|
||||||
this.sealedAndSigned = sealedAndSigned;
|
this.sealedAndSigned = sealedAndSigned;
|
||||||
|
this.blurredAddressHash = blurredAddressHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,6 +35,7 @@ public final class SealedAndSignedMessage implements MailboxMessage {
|
||||||
return "SealedAndSignedMessage{" +
|
return "SealedAndSignedMessage{" +
|
||||||
"networkId=" + networkId +
|
"networkId=" + networkId +
|
||||||
", sealedAndSigned=" + sealedAndSigned +
|
", sealedAndSigned=" + sealedAndSigned +
|
||||||
|
", receiverAddressMaskHash.hashCode()=" + Arrays.toString(blurredAddressHash).hashCode() +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,10 @@ public class Address implements Serializable {
|
||||||
return hostName + ":" + port;
|
return hostName + ":" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAddressMask() {
|
||||||
|
return getFullAddress().substring(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -7,10 +7,11 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
import io.bitsquare.app.Log;
|
import io.bitsquare.app.Log;
|
||||||
import io.bitsquare.app.ProgramArguments;
|
import io.bitsquare.app.ProgramArguments;
|
||||||
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.crypto.CryptoException;
|
import io.bitsquare.common.crypto.CryptoException;
|
||||||
|
import io.bitsquare.common.crypto.Hash;
|
||||||
import io.bitsquare.common.crypto.KeyRing;
|
import io.bitsquare.common.crypto.KeyRing;
|
||||||
import io.bitsquare.common.crypto.PubKeyRing;
|
import io.bitsquare.common.crypto.PubKeyRing;
|
||||||
import io.bitsquare.common.crypto.SealedAndSigned;
|
|
||||||
import io.bitsquare.crypto.EncryptionService;
|
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.*;
|
||||||
|
@ -43,6 +44,7 @@ import java.math.BigInteger;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -53,6 +55,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
public class P2PService implements SetupListener, MessageListener, ConnectionListener, PeerListener {
|
public class P2PService implements SetupListener, MessageListener, ConnectionListener, PeerListener {
|
||||||
private static final Logger log = LoggerFactory.getLogger(P2PService.class);
|
private static final Logger log = LoggerFactory.getLogger(P2PService.class);
|
||||||
|
|
||||||
|
private static final int RETRY_GET_DATA = 10 * 1000;
|
||||||
|
|
||||||
private final SeedNodesRepository seedNodesRepository;
|
private final SeedNodesRepository seedNodesRepository;
|
||||||
private final int port;
|
private final int port;
|
||||||
private final File torDir;
|
private final File torDir;
|
||||||
|
@ -79,6 +83,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
private final BooleanProperty authenticated = new SimpleBooleanProperty();
|
private final BooleanProperty authenticated = new SimpleBooleanProperty();
|
||||||
private MonadicBinding<Boolean> readyForAuthentication;
|
private MonadicBinding<Boolean> readyForAuthentication;
|
||||||
public final IntegerProperty numAuthenticatedPeers = new SimpleIntegerProperty(0);
|
public final IntegerProperty numAuthenticatedPeers = new SimpleIntegerProperty(0);
|
||||||
|
@Nullable
|
||||||
|
private byte[] blurredAddressHash = null;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -181,11 +187,15 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
if (encryptionService != null) {
|
if (encryptionService != null) {
|
||||||
try {
|
try {
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = (SealedAndSignedMessage) message;
|
SealedAndSignedMessage sealedAndSignedMessage = (SealedAndSignedMessage) message;
|
||||||
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(
|
if (verifyBlurredAddressHash(sealedAndSignedMessage)) {
|
||||||
sealedAndSignedMessage.sealedAndSigned);
|
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(
|
||||||
log.info("Received SealedAndSignedMessage and decrypted it: " + decryptedMsgWithPubKey);
|
sealedAndSignedMessage.sealedAndSigned);
|
||||||
decryptedMailListeners.stream().forEach(
|
log.info("Received SealedAndSignedMessage and decrypted it: " + decryptedMsgWithPubKey);
|
||||||
e -> e.onMailMessage(decryptedMsgWithPubKey, connection.getPeerAddress()));
|
decryptedMailListeners.stream().forEach(
|
||||||
|
e -> e.onMailMessage(decryptedMsgWithPubKey, connection.getPeerAddress()));
|
||||||
|
} else {
|
||||||
|
log.info("Wrong receiverAddressMaskHash. The message is not intended for us.");
|
||||||
|
}
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
log.info("Decryption of SealedAndSignedMessage failed. " +
|
log.info("Decryption of SealedAndSignedMessage failed. " +
|
||||||
"That is expected if the message is not intended for us.");
|
"That is expected if the message is not intended for us.");
|
||||||
|
@ -194,6 +204,11 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean verifyBlurredAddressHash(SealedAndSignedMessage sealedAndSignedMessage) {
|
||||||
|
return blurredAddressHash != null &&
|
||||||
|
Arrays.equals(blurredAddressHash, sealedAndSignedMessage.blurredAddressHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ConnectionListener implementation
|
// ConnectionListener implementation
|
||||||
|
@ -277,6 +292,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
checkArgument(networkNode.getAddress() != null, "Address must be set when we have the hidden service ready");
|
checkArgument(networkNode.getAddress() != null, "Address must be set when we have the hidden service ready");
|
||||||
|
|
||||||
|
blurredAddressHash = Hash.getHash(getAddress().getAddressMask());
|
||||||
|
|
||||||
p2pServiceListeners.stream().forEach(e -> e.onHiddenServicePublished());
|
p2pServiceListeners.stream().forEach(e -> e.onHiddenServicePublished());
|
||||||
|
|
||||||
// 3. (or 2.). Step: Hidden service is published
|
// 3. (or 2.). Step: Hidden service is published
|
||||||
|
@ -303,6 +320,13 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
public void onSuccess(@Nullable Connection connection) {
|
public void onSuccess(@Nullable Connection connection) {
|
||||||
log.info("Send GetAllDataMessage to " + candidate + " succeeded.");
|
log.info("Send GetAllDataMessage to " + candidate + " succeeded.");
|
||||||
connectedSeedNode = candidate;
|
connectedSeedNode = candidate;
|
||||||
|
|
||||||
|
// In case we get called by a retry we check if we need authenticate as well
|
||||||
|
if (hiddenServicePublished.get() && !authenticated.get()) {
|
||||||
|
peerGroup.authenticateSeedNode(connectedSeedNode);
|
||||||
|
} else {
|
||||||
|
log.debug("No connected seedNode available.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,23 +341,26 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
log.info("There is no seed node available for requesting data. That is expected for the first seed node.");
|
log.info("There is no seed node available for requesting data. " +
|
||||||
|
"That is expected if no seed node is available.\n" +
|
||||||
|
"We will try again after {} ms", RETRY_GET_DATA);
|
||||||
setRequestingDataCompleted();
|
setRequestingDataCompleted();
|
||||||
|
|
||||||
|
UserThread.runAfter(() -> sendGetDataRequest(peerGroup.getSeedNodeAddresses()),
|
||||||
|
RETRY_GET_DATA, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRequestingDataCompleted() {
|
private void setRequestingDataCompleted() {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
// 2. (or 3.) Step: We got all data loaded
|
// 2. (or 3.) Step: We got all data loaded (or no seed node available - should not happen in real operation)
|
||||||
if (!requestingDataCompleted.get())
|
requestingDataCompleted.set(true);
|
||||||
requestingDataCompleted.set(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Step: hiddenServicePublished and allDataLoaded. We start authenticate to the connected seed node.
|
// 4. Step: hiddenServicePublished and allDataLoaded. We start authenticate to the connected seed node.
|
||||||
private void tryAuthenticateSeedNode() {
|
private void tryAuthenticateSeedNode() {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
if (connectedSeedNode != null) {
|
if (connectedSeedNode != null) {
|
||||||
log.trace("authenticateSeedNode");
|
|
||||||
peerGroup.authenticateSeedNode(connectedSeedNode);
|
peerGroup.authenticateSeedNode(connectedSeedNode);
|
||||||
} else {
|
} else {
|
||||||
log.debug("No connected seedNode available.");
|
log.debug("No connected seedNode available.");
|
||||||
|
@ -436,7 +463,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
if (encryptionService != null) {
|
if (encryptionService != null) {
|
||||||
try {
|
try {
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
||||||
encryptionService.encryptAndSign(pubKeyRing, message));
|
encryptionService.encryptAndSign(pubKeyRing, message), Hash.getHash(peerAddress.getAddressMask()));
|
||||||
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
|
||||||
|
@ -482,7 +509,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
if (encryptionService != null) {
|
if (encryptionService != null) {
|
||||||
try {
|
try {
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
|
||||||
encryptionService.encryptAndSign(peersPubKeyRing, message));
|
encryptionService.encryptAndSign(peersPubKeyRing, message), Hash.getHash(peerAddress.getAddressMask()));
|
||||||
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
|
||||||
|
@ -639,22 +666,18 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public boolean isAuthenticated() {
|
public boolean isAuthenticated() {
|
||||||
Log.traceCall();
|
|
||||||
return authenticated.get();
|
return authenticated.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkNode getNetworkNode() {
|
public NetworkNode getNetworkNode() {
|
||||||
Log.traceCall();
|
|
||||||
return networkNode;
|
return networkNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PeerGroup getPeerGroup() {
|
public PeerGroup getPeerGroup() {
|
||||||
Log.traceCall();
|
|
||||||
return peerGroup;
|
return peerGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address getAddress() {
|
public Address getAddress() {
|
||||||
Log.traceCall();
|
|
||||||
return networkNode.getAddress();
|
return networkNode.getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,25 +698,34 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
private void tryDecryptMailboxData(ProtectedMailboxData mailboxData) {
|
private void tryDecryptMailboxData(ProtectedMailboxData mailboxData) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
if (encryptionService != null) {
|
if (encryptionService != null) {
|
||||||
ExpirablePayload data = mailboxData.expirablePayload;
|
ExpirablePayload expirablePayload = mailboxData.expirablePayload;
|
||||||
if (data instanceof ExpirableMailboxPayload) {
|
if (expirablePayload instanceof ExpirableMailboxPayload) {
|
||||||
ExpirableMailboxPayload mailboxEntry = (ExpirableMailboxPayload) data;
|
ExpirableMailboxPayload expirableMailboxPayload = (ExpirableMailboxPayload) expirablePayload;
|
||||||
SealedAndSigned sealedAndSigned = mailboxEntry.sealedAndSignedMessage.sealedAndSigned;
|
SealedAndSignedMessage sealedAndSignedMessage = expirableMailboxPayload.sealedAndSignedMessage;
|
||||||
try {
|
if (verifyBlurredAddressHash(sealedAndSignedMessage)) {
|
||||||
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(sealedAndSigned);
|
try {
|
||||||
if (decryptedMsgWithPubKey.message instanceof MailboxMessage) {
|
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(
|
||||||
MailboxMessage mailboxMessage = (MailboxMessage) decryptedMsgWithPubKey.message;
|
sealedAndSignedMessage.sealedAndSigned);
|
||||||
Address senderAddress = mailboxMessage.getSenderAddress();
|
if (decryptedMsgWithPubKey.message instanceof MailboxMessage) {
|
||||||
checkNotNull(senderAddress, "senderAddress must not be null for mailbox messages");
|
MailboxMessage mailboxMessage = (MailboxMessage) decryptedMsgWithPubKey.message;
|
||||||
|
Address senderAddress = mailboxMessage.getSenderAddress();
|
||||||
|
checkNotNull(senderAddress, "senderAddress must not be null for mailbox messages");
|
||||||
|
|
||||||
mailboxMap.put(decryptedMsgWithPubKey, mailboxData);
|
mailboxMap.put(decryptedMsgWithPubKey, mailboxData);
|
||||||
log.trace("Decryption of SealedAndSignedMessage succeeded. senderAddress="
|
log.trace("Decryption of SealedAndSignedMessage succeeded. senderAddress="
|
||||||
+ senderAddress + " / my address=" + getAddress());
|
+ senderAddress + " / my address=" + getAddress());
|
||||||
decryptedMailboxListeners.stream().forEach(
|
decryptedMailboxListeners.stream().forEach(
|
||||||
e -> e.onMailboxMessageAdded(decryptedMsgWithPubKey, senderAddress));
|
e -> e.onMailboxMessageAdded(decryptedMsgWithPubKey, senderAddress));
|
||||||
|
} else {
|
||||||
|
log.warn("tryDecryptMailboxData: Expected MailboxMessage but got other type. " +
|
||||||
|
"decryptedMsgWithPubKey.message=", decryptedMsgWithPubKey.message);
|
||||||
|
}
|
||||||
|
} catch (CryptoException e) {
|
||||||
|
log.trace("Decryption of SealedAndSignedMessage failed. " +
|
||||||
|
"That is expected if the message is not intended for us. " + e.getMessage());
|
||||||
}
|
}
|
||||||
} catch (CryptoException e) {
|
} else {
|
||||||
log.trace("Decryption of SealedAndSignedMessage failed. That is expected if the message is not intended for us. " + e.getMessage());
|
log.info("Wrong blurredAddressHash. The message is not intended for us.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,7 @@ import java.util.concurrent.*;
|
||||||
public class Connection implements MessageListener {
|
public class Connection implements MessageListener {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Connection.class);
|
private static final Logger log = LoggerFactory.getLogger(Connection.class);
|
||||||
private static final int MAX_MSG_SIZE = 5 * 1024 * 1024; // 5 MB of compressed data
|
private static final int MAX_MSG_SIZE = 5 * 1024 * 1024; // 5 MB of compressed data
|
||||||
private static final int MAX_ILLEGAL_REQUESTS = 5;
|
|
||||||
private static final int SEND_MESSAGE_TIMEOUT = 10 * 1000; // 10 sec.
|
|
||||||
private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min.
|
private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min.
|
||||||
private InputHandler inputHandler;
|
|
||||||
private volatile boolean isAuthenticated;
|
|
||||||
|
|
||||||
public static int getMaxMsgSize() {
|
public static int getMaxMsgSize() {
|
||||||
return MAX_MSG_SIZE;
|
return MAX_MSG_SIZE;
|
||||||
|
@ -43,21 +39,20 @@ public class Connection implements MessageListener {
|
||||||
private final Socket socket;
|
private final Socket socket;
|
||||||
private final MessageListener messageListener;
|
private final MessageListener messageListener;
|
||||||
private final ConnectionListener connectionListener;
|
private final ConnectionListener connectionListener;
|
||||||
|
|
||||||
private final String portInfo;
|
private final String portInfo;
|
||||||
private final String uid = UUID.randomUUID().toString();
|
private final String uid = UUID.randomUUID().toString();
|
||||||
;
|
|
||||||
private final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
|
private final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
|
||||||
|
// holder of state shared between InputHandler and Connection
|
||||||
|
private final SharedSpace sharedSpace;
|
||||||
|
|
||||||
// set in init
|
// set in init
|
||||||
|
private InputHandler inputHandler;
|
||||||
private ObjectOutputStream objectOutputStream;
|
private ObjectOutputStream objectOutputStream;
|
||||||
// holder of state shared between InputHandler and Connection
|
|
||||||
private SharedSpace sharedSpace;
|
|
||||||
|
|
||||||
// mutable data, set from other threads but not changed internally.
|
// mutable data, set from other threads but not changed internally.
|
||||||
@Nullable
|
@Nullable
|
||||||
private Address peerAddress;
|
private Address peerAddress;
|
||||||
|
private volatile boolean isAuthenticated;
|
||||||
private volatile boolean stopped;
|
private volatile boolean stopped;
|
||||||
|
|
||||||
//TODO got java.util.zip.DataFormatException: invalid distance too far back
|
//TODO got java.util.zip.DataFormatException: invalid distance too far back
|
||||||
|
@ -75,6 +70,8 @@ public class Connection implements MessageListener {
|
||||||
this.messageListener = messageListener;
|
this.messageListener = messageListener;
|
||||||
this.connectionListener = connectionListener;
|
this.connectionListener = connectionListener;
|
||||||
|
|
||||||
|
sharedSpace = new SharedSpace(this, socket);
|
||||||
|
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
if (socket.getLocalPort() == 0)
|
if (socket.getLocalPort() == 0)
|
||||||
portInfo = "port=" + socket.getPort();
|
portInfo = "port=" + socket.getPort();
|
||||||
|
@ -86,7 +83,7 @@ public class Connection implements MessageListener {
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
sharedSpace = new SharedSpace(this, socket);
|
|
||||||
try {
|
try {
|
||||||
socket.setSoTimeout(SOCKET_TIMEOUT);
|
socket.setSoTimeout(SOCKET_TIMEOUT);
|
||||||
// Need to access first the ObjectOutputStream otherwise the ObjectInputStream would block
|
// Need to access first the ObjectOutputStream otherwise the ObjectInputStream would block
|
||||||
|
|
|
@ -124,8 +124,8 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
|
||||||
public void run() {
|
public void run() {
|
||||||
Thread.currentThread().setName("TimerTask-" + new Random().nextInt(10000));
|
Thread.currentThread().setName("TimerTask-" + new Random().nextInt(10000));
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
String message = "Timeout occurred when trying to create Socket.";
|
String message = "Timeout occurred when tried to create Socket to peer: " + peerAddress;
|
||||||
log.warn(message);
|
log.info(message);
|
||||||
resultFuture.setException(new TimeoutException(message));
|
resultFuture.setException(new TimeoutException(message));
|
||||||
}
|
}
|
||||||
}, CREATE_SOCKET_TIMEOUT);
|
}, CREATE_SOCKET_TIMEOUT);
|
||||||
|
|
|
@ -44,11 +44,11 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
MAX_CONNECTIONS = maxConnections;
|
MAX_CONNECTIONS = maxConnections;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int SEND_PING_INTERVAL = new Random().nextInt(2 * 60 * 1000) + 2 * 60 * 1000 * 1000; // 2-4 min.
|
private static final int SEND_PING_INTERVAL = new Random().nextInt(5 * 60 * 1000) + 5 * 60 * 1000;
|
||||||
private static final int GET_PEERS_INTERVAL = 10000 * 1000;//new Random().nextInt(1 * 60 * 1000) + 1 * 60 * 1000; // 1-2 min.
|
private static final int PING_AFTER_CONNECTION_INACTIVITY = 30 * 1000;
|
||||||
private static final int PING_AFTER_CONNECTION_INACTIVITY = 30 * 1000 * 1000;
|
private static final int GET_PEERS_INTERVAL = new Random().nextInt(1 * 60 * 1000) + 1 * 60 * 1000; // 1-2 min.
|
||||||
private static final int MAX_REPORTED_PEERS = 1000 * 1000;
|
private static final int RETRY_FILL_AUTH_PEERS = GET_PEERS_INTERVAL + 5000;
|
||||||
private static final int RETRY_FILL_AUTH_PEERS = 10000 * 1000;
|
private static final int MAX_REPORTED_PEERS = 1000;
|
||||||
|
|
||||||
private final NetworkNode networkNode;
|
private final NetworkNode networkNode;
|
||||||
private final Set<Address> seedNodeAddresses;
|
private final Set<Address> seedNodeAddresses;
|
||||||
|
@ -110,9 +110,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect(Reason reason, Connection connection) {
|
public void onDisconnect(Reason reason, Connection connection) {
|
||||||
log.debug("onDisconnect connection=" + connection + " / reason=" + reason);
|
log.debug("onDisconnect connection=" + connection + " / reason=" + reason);
|
||||||
// only removes authenticated nodes
|
removePeer(connection.getPeerAddress());
|
||||||
if (connection.isAuthenticated())
|
|
||||||
removePeer(connection.getPeerAddress());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -512,7 +510,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
});
|
});
|
||||||
}, 5, 10));
|
}, 5, 10));
|
||||||
} else {
|
} else {
|
||||||
log.trace("No peers available for requesting data.");
|
log.info("No peers available for requesting data.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,12 +590,10 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private Map<Address, Peer> getAuthenticatedPeers() {
|
private Map<Address, Peer> getAuthenticatedPeers() {
|
||||||
Log.traceCall();
|
|
||||||
return authenticatedPeers;
|
return authenticatedPeers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Address> getAllPeerAddresses() {
|
public Set<Address> getAllPeerAddresses() {
|
||||||
Log.traceCall();
|
|
||||||
Set<Address> allPeerAddresses = new HashSet<>(reportedPeerAddresses);
|
Set<Address> allPeerAddresses = new HashSet<>(reportedPeerAddresses);
|
||||||
allPeerAddresses.addAll(authenticatedPeers.values().stream()
|
allPeerAddresses.addAll(authenticatedPeers.values().stream()
|
||||||
.map(e -> e.address).collect(Collectors.toSet()));
|
.map(e -> e.address).collect(Collectors.toSet()));
|
||||||
|
@ -605,7 +601,6 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Address> getSeedNodeAddresses() {
|
public Set<Address> getSeedNodeAddresses() {
|
||||||
Log.traceCall();
|
|
||||||
return seedNodeAddresses;
|
return seedNodeAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,13 +700,11 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printAllPeers() {
|
public void printAllPeers() {
|
||||||
Log.traceCall();
|
|
||||||
printAuthenticatedPeers();
|
printAuthenticatedPeers();
|
||||||
printReportedPeers();
|
printReportedPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printAuthenticatedPeers() {
|
public void printAuthenticatedPeers() {
|
||||||
Log.traceCall();
|
|
||||||
StringBuilder result = new StringBuilder("\n\n------------------------------------------------------------\n" +
|
StringBuilder result = new StringBuilder("\n\n------------------------------------------------------------\n" +
|
||||||
"Authenticated peers for node " + getMyAddress() + ":");
|
"Authenticated peers for node " + getMyAddress() + ":");
|
||||||
authenticatedPeers.values().stream().forEach(e -> result.append("\n").append(e.address));
|
authenticatedPeers.values().stream().forEach(e -> result.append("\n").append(e.address));
|
||||||
|
@ -720,7 +713,6 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printReportedPeers() {
|
public void printReportedPeers() {
|
||||||
Log.traceCall();
|
|
||||||
StringBuilder result = new StringBuilder("\n\n------------------------------------------------------------\n" +
|
StringBuilder result = new StringBuilder("\n\n------------------------------------------------------------\n" +
|
||||||
"Reported peers for node " + getMyAddress() + ":");
|
"Reported peers for node " + getMyAddress() + ":");
|
||||||
reportedPeerAddresses.stream().forEach(e -> result.append("\n").append(e));
|
reportedPeerAddresses.stream().forEach(e -> result.append("\n").append(e));
|
||||||
|
|
|
@ -113,8 +113,9 @@ public class ProtectedExpirableDataStorage implements MessageListener {
|
||||||
removeMailboxData(((RemoveMailboxDataMessage) message).data, connection.getPeerAddress());
|
removeMailboxData(((RemoveMailboxDataMessage) message).data, connection.getPeerAddress());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Connection is not authenticated yet. We don't accept storage operations form non-authenticated nodes.");
|
log.warn("Connection is not authenticated yet. " +
|
||||||
log.warn("Connection = " + connection);
|
"We don't accept storage operations from non-authenticated nodes.");
|
||||||
|
log.trace("Connection = " + connection);
|
||||||
connection.reportIllegalRequest(IllegalRequest.NotAuthenticated);
|
connection.reportIllegalRequest(IllegalRequest.NotAuthenticated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,7 @@ package io.bitsquare.crypto;
|
||||||
|
|
||||||
|
|
||||||
import io.bitsquare.app.Version;
|
import io.bitsquare.app.Version;
|
||||||
import io.bitsquare.common.crypto.CryptoException;
|
import io.bitsquare.common.crypto.*;
|
||||||
import io.bitsquare.common.crypto.KeyRing;
|
|
||||||
import io.bitsquare.common.crypto.KeyStorage;
|
|
||||||
import io.bitsquare.common.crypto.PubKeyRing;
|
|
||||||
import io.bitsquare.common.util.Utilities;
|
import io.bitsquare.common.util.Utilities;
|
||||||
import io.bitsquare.p2p.Address;
|
import io.bitsquare.p2p.Address;
|
||||||
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
|
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
|
||||||
|
@ -75,7 +72,7 @@ public class EncryptionServiceTests {
|
||||||
public void testDecryptAndVerifyMessage() throws CryptoException {
|
public void testDecryptAndVerifyMessage() throws CryptoException {
|
||||||
EncryptionService encryptionService = new EncryptionService(keyRing);
|
EncryptionService encryptionService = new EncryptionService(keyRing);
|
||||||
TestMessage data = new TestMessage("test");
|
TestMessage data = new TestMessage("test");
|
||||||
SealedAndSignedMessage encrypted = new SealedAndSignedMessage(encryptionService.encryptAndSign(pubKeyRing, data));
|
SealedAndSignedMessage encrypted = new SealedAndSignedMessage(encryptionService.encryptAndSign(pubKeyRing, data), Hash.getHash("aa"));
|
||||||
DecryptedMsgWithPubKey decrypted = encryptionService.decryptAndVerify(encrypted.sealedAndSigned);
|
DecryptedMsgWithPubKey decrypted = encryptionService.decryptAndVerify(encrypted.sealedAndSigned);
|
||||||
assertEquals(data.data, ((TestMessage) decrypted.message).data);
|
assertEquals(data.data, ((TestMessage) decrypted.message).data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ public class ProtectedDataStorageTest {
|
||||||
KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
|
KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
|
||||||
// sender
|
// sender
|
||||||
MockMessage mockMessage = new MockMessage("MockMessage");
|
MockMessage mockMessage = new MockMessage("MockMessage");
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService1.encryptAndSign(keyRing1.getPubKeyRing(), mockMessage));
|
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService1.encryptAndSign(keyRing1.getPubKeyRing(), mockMessage), Hash.getHash("aa"));
|
||||||
ExpirableMailboxPayload expirableMailboxPayload = new ExpirableMailboxPayload(sealedAndSignedMessage,
|
ExpirableMailboxPayload expirableMailboxPayload = new ExpirableMailboxPayload(sealedAndSignedMessage,
|
||||||
keyRing1.getSignatureKeyPair().getPublic(),
|
keyRing1.getSignatureKeyPair().getPublic(),
|
||||||
keyRing2.getSignatureKeyPair().getPublic());
|
keyRing2.getSignatureKeyPair().getPublic());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue