issue #4: prevent connections to self, select random nodes to connect to
This commit is contained in:
		| @@ -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); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -230,4 +230,8 @@ public class Security { | |||||||
|             throw new RuntimeException(e); |             throw new RuntimeException(e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static long randomNonce() { | ||||||
|  |         return RANDOM.nextLong(); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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")) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user