issue #4: prevent connections to self, select random nodes to connect to

This commit is contained in:
Christian Basler 2015-06-13 17:37:55 +02:00
parent bd5bf76904
commit ed0d1c2911
4 changed files with 21 additions and 4 deletions

View File

@ -52,6 +52,7 @@ public class InternalContext {
private final int port; private final int port;
private long networkNonceTrialsPerByte = 1000; private long networkNonceTrialsPerByte = 1000;
private long networkExtraBytes = 1000; private long networkExtraBytes = 1000;
private long clientNonce;
public InternalContext(BitmessageContext.Builder builder) { public InternalContext(BitmessageContext.Builder builder) {
this.inventory = builder.inventory; this.inventory = builder.inventory;
@ -60,6 +61,7 @@ public class InternalContext {
this.addressRepository = builder.addressRepo; this.addressRepository = builder.addressRepo;
this.messageRepository = builder.messageRepo; this.messageRepository = builder.messageRepo;
this.proofOfWorkEngine = builder.proofOfWorkEngine; this.proofOfWorkEngine = builder.proofOfWorkEngine;
this.clientNonce = Security.randomNonce();
port = builder.port; port = builder.port;
streams = builder.streams; streams = builder.streams;
@ -212,6 +214,14 @@ public class InternalContext {
} }
} }
public long getClientNonce() {
return clientNonce;
}
public void setClientNonce(long clientNonce) {
this.clientNonce = clientNonce;
}
public interface ContextHolder { public interface ContextHolder {
void setContext(InternalContext context); void setContext(InternalContext context);
} }

View File

@ -230,4 +230,8 @@ public class Security {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public static long randomNonce() {
return RANDOM.nextLong();
}
} }

View File

@ -102,7 +102,10 @@ public class Connection implements Runnable {
switch (msg.getPayload().getCommand()) { switch (msg.getPayload().getCommand()) {
case VERSION: case VERSION:
Version payload = (Version) msg.getPayload(); Version payload = (Version) msg.getPayload();
if (payload.getVersion() >= BitmessageContext.CURRENT_VERSION) { if (payload.getNonce() == ctx.getClientNonce()) {
LOG.info("Tried to connect to self, disconnecting.");
disconnect();
} else if (payload.getVersion() >= BitmessageContext.CURRENT_VERSION) {
this.version = payload.getVersion(); this.version = payload.getVersion();
this.streams = payload.getStreams(); this.streams = payload.getStreams();
send(new VerAck()); send(new VerAck());
@ -120,8 +123,8 @@ public class Connection implements Runnable {
} }
break; break;
default: default:
throw new RuntimeException("Command 'version' or 'verack' expected, but was " throw new RuntimeException("Command 'version' or 'verack' expected, but was '"
+ msg.getPayload().getCommand()); + msg.getPayload().getCommand() + "'");
} }
} }
if (socket.isClosed()) state = DISCONNECTED; if (socket.isClosed()) state = DISCONNECTED;

View File

@ -37,7 +37,7 @@ public class JdbcNodeRegistry extends JdbcHelper implements NodeRegistry {
List<NetworkAddress> result = new LinkedList<>(); List<NetworkAddress> result = new LinkedList<>();
try (Connection connection = config.getConnection()) { try (Connection connection = config.getConnection()) {
Statement stmt = connection.createStatement(); Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM Node WHERE stream IN (" + join(streams) + ") LIMIT " + limit); ResultSet rs = stmt.executeQuery("SELECT * FROM Node WHERE stream IN (" + join(streams) + ") ORDER BY RANDOM() LIMIT " + limit);
while (rs.next()) { while (rs.next()) {
result.add(new NetworkAddress.Builder() result.add(new NetworkAddress.Builder()
.ipv6(rs.getBytes("ip")) .ipv6(rs.getBytes("ip"))