This breaks a lot of things, but it seems necessary. Implemented the resending mechanism and fixed many problems on the way, but tests and triggers are still to do.

This commit is contained in:
2016-05-20 07:32:41 +02:00
parent e44dd967d0
commit 43f42dd400
17 changed files with 202 additions and 52 deletions

View File

@ -72,6 +72,7 @@ class Connection {
private final ReaderRunnable reader = new ReaderRunnable();
private final WriterRunnable writer = new WriterRunnable();
private final DefaultNetworkHandler networkHandler;
private final long clientNonce;
private volatile State state;
private InputStream in;
@ -83,22 +84,23 @@ class Connection {
private long lastObjectTime;
public Connection(InternalContext context, Mode mode, Socket socket, MessageListener listener,
Set<InventoryVector> requestedObjectsMap) throws IOException {
Set<InventoryVector> requestedObjectsMap, long clientNonce) throws IOException {
this(context, mode, listener, socket, requestedObjectsMap,
Collections.newSetFromMap(new ConcurrentHashMap<InventoryVector, Boolean>(10_000)),
new NetworkAddress.Builder().ip(socket.getInetAddress()).port(socket.getPort()).stream(1).build(),
0);
0, clientNonce);
}
public Connection(InternalContext context, Mode mode, NetworkAddress node, MessageListener listener,
Set<InventoryVector> requestedObjectsMap) {
Set<InventoryVector> requestedObjectsMap, long clientNonce) {
this(context, mode, listener, new Socket(), requestedObjectsMap,
Collections.newSetFromMap(new ConcurrentHashMap<InventoryVector, Boolean>(10_000)),
node, 0);
node, 0, clientNonce);
}
private Connection(InternalContext context, Mode mode, MessageListener listener, Socket socket,
Set<InventoryVector> commonRequestedObjects, Set<InventoryVector> requestedObjects, NetworkAddress node, long syncTimeout) {
Set<InventoryVector> commonRequestedObjects, Set<InventoryVector> requestedObjects,
NetworkAddress node, long syncTimeout, long clientNonce) {
this.startTime = UnixTime.now();
this.ctx = context;
this.mode = mode;
@ -112,6 +114,7 @@ class Connection {
this.syncTimeout = (syncTimeout > 0 ? UnixTime.now(+syncTimeout) : 0);
this.ivCache = new ConcurrentHashMap<>();
this.networkHandler = (DefaultNetworkHandler) ctx.getNetworkHandler();
this.clientNonce = clientNonce;
}
public static Connection sync(InternalContext ctx, InetAddress address, int port, MessageListener listener,
@ -120,7 +123,7 @@ class Connection {
new HashSet<InventoryVector>(),
new HashSet<InventoryVector>(),
new NetworkAddress.Builder().ip(address).port(port).stream(1).build(),
timeoutInSeconds);
timeoutInSeconds, cryptography().randomNonce());
}
public long getStartTime() {
@ -362,7 +365,7 @@ class Connection {
try (Socket socket = Connection.this.socket) {
initSocket(socket);
if (mode == CLIENT || mode == SYNC) {
send(new Version.Builder().defaults().addrFrom(host).addrRecv(node).build());
send(new Version.Builder().defaults(clientNonce).addrFrom(host).addrRecv(node).build());
}
while (state != DISCONNECTED) {
if (mode != SYNC) {
@ -446,7 +449,7 @@ class Connection {
send(new VerAck());
switch (mode) {
case SERVER:
send(new Version.Builder().defaults().addrFrom(host).addrRecv(node).build());
send(new Version.Builder().defaults(clientNonce).addrFrom(host).addrRecv(node).build());
break;
case CLIENT:
case SYNC:

View File

@ -38,15 +38,17 @@ public class ConnectionOrganizer implements Runnable {
private final InternalContext ctx;
private final DefaultNetworkHandler networkHandler;
private final NetworkHandler.MessageListener listener;
private final long clientNonce;
private Connection initialConnection;
public ConnectionOrganizer(InternalContext ctx,
DefaultNetworkHandler networkHandler,
NetworkHandler.MessageListener listener) {
NetworkHandler.MessageListener listener, long clientNonce) {
this.ctx = ctx;
this.networkHandler = networkHandler;
this.listener = listener;
this.clientNonce = clientNonce;
}
@Override
@ -91,7 +93,8 @@ public class ConnectionOrganizer implements Runnable {
NETWORK_MAGIC_NUMBER - active, ctx.getStreams());
boolean first = active == 0 && initialConnection == null;
for (NetworkAddress address : addresses) {
Connection c = new Connection(ctx, CLIENT, address, listener, networkHandler.requestedObjects);
Connection c = new Connection(ctx, CLIENT, address, listener,
networkHandler.requestedObjects, clientNonce);
if (first) {
initialConnection = c;
first = false;

View File

@ -28,7 +28,6 @@ import ch.dissem.bitmessage.factory.Factory;
import ch.dissem.bitmessage.ports.NetworkHandler;
import ch.dissem.bitmessage.utils.Collections;
import ch.dissem.bitmessage.utils.Property;
import ch.dissem.bitmessage.utils.ThreadFactoryBuilder;
import java.io.IOException;
import java.net.InetAddress;
@ -109,9 +108,9 @@ public class DefaultNetworkHandler implements NetworkHandler, ContextHolder {
try {
running = true;
connections.clear();
server = new ServerRunnable(ctx, this, listener);
server = new ServerRunnable(ctx, this, listener, ctx.getClientNonce());
pool.execute(server);
pool.execute(new ConnectionOrganizer(ctx, this, listener));
pool.execute(new ConnectionOrganizer(ctx, this, listener, ctx.getClientNonce()));
} catch (IOException e) {
throw new ApplicationException(e);
}

View File

@ -37,12 +37,15 @@ public class ServerRunnable implements Runnable, Closeable {
private final ServerSocket serverSocket;
private final DefaultNetworkHandler networkHandler;
private final NetworkHandler.MessageListener listener;
private final long clientNonce;
public ServerRunnable(InternalContext ctx, DefaultNetworkHandler networkHandler, NetworkHandler.MessageListener listener) throws IOException {
public ServerRunnable(InternalContext ctx, DefaultNetworkHandler networkHandler,
NetworkHandler.MessageListener listener, long clientNonce) throws IOException {
this.ctx = ctx;
this.networkHandler = networkHandler;
this.listener = listener;
this.serverSocket = new ServerSocket(ctx.getPort());
this.clientNonce = clientNonce;
}
@Override
@ -52,7 +55,7 @@ public class ServerRunnable implements Runnable, Closeable {
Socket socket = serverSocket.accept();
socket.setSoTimeout(Connection.READ_TIMEOUT);
networkHandler.startConnection(new Connection(ctx, SERVER, socket, listener,
networkHandler.requestedObjects));
networkHandler.requestedObjects, clientNonce));
} catch (IOException e) {
LOG.debug(e.getMessage(), e);
}