private void route(JsonObject message, int fromNode) { String text = message.getString("text", null); int from = message.getInt("from", -1); int to = message.getInt("to", -1); if (fromNode == from && to >= 0 && text != null) { SwingUtilities.invokeLater( () -> { messages.addPacket(from, to, text, getByNode(from).getNetwork()); }); if (to == 0) { for (int i = 0; i < connections.size(); i++) { Connection c = connections.get(i); if (c != null && links.isNeighbour(fromNode, c.getNode())) { send(c, text, from, to); } } } else { Connection c = getByNode(to); if (c != null && links.isNeighbour(from, to)) { send(c, text, from, to); } } } }
public void addConnection(BufferedOutputStream os, InputStream isr, InetAddress a) throws HandshakeException { final Connection c = new Connection(os, isr); int setNode = c.getNode(); boolean keep = false; if (session == c.getSession() && setNode != 0) { // Loop through the connections and find the node number for (int i = 0; i < connections.size(); i++) { Connection cc = connections.get(i); if (cc.getNode() == setNode) { // Keep old node Name c.setHostname(cc.getHostname()); c.setNetwork(cc.getNetwork()); final int actualNode = i; SwingUtilities.invokeLater( () -> { // This is not a structural modification so will not // cause Thread problems connections.set(actualNode, c); }); keep = true; synchronized (queue) { // add the appropriate status reply queue.add(new ConnectMessage(c, -1, true)); } break; } } } if (!keep) { if (started) { throw new HandshakeException("Cannot add new connections after the game has started"); } c.setup(session); try { SwingUtilities.invokeAndWait( () -> { connections.addElement(c); }); } catch (InvocationTargetException | InterruptedException e) { throw new HandshakeException("Failed to add new connection"); } (new ConnectMessage(c, -1, true)).send(); } }
private Connection getByNode(int node) { for (int i = 0; i < connections.size(); i++) { Connection c = connections.get(i); if (c.getNode() == node) { return c; } } return null; }
// This method can only be executed in the EDT so is safe from Connections // updates public void updateStatus() { // The first update triggers network building. if (!started) { started = true; int maxNets = Math.max(1, connections.size() / MIN_PER_NET); int numNets = Math.min((connections.size() + MAX_PER_NET - 1) / MAX_PER_NET, maxNets); createCycles(numNets); // Begin to check for messages. synchronized (queue) { this.start(); } } int l = connections.size(); List<String> texts = null; if (links.getOffset() != 0 && !links.isCheckwhois()) { texts = new ArrayList<String>(); Texts.choose_messages(texts, l, links.getCorruptionRate() > 0); } // mark any current messages out of date startTime = System.currentTimeMillis(); synchronized (queue) { for (int i = 0; i < l; i++) { Connection c = connections.get(i); if (c != null) { if (links.getOffset() == 0) { queue.add(new TaskMessage(c, -1, links)); } else { int recipient = cycles.get(c.getNetwork()).offsetNode(c.getNode(), links.getOffset()); System.out.println("Node:" + c.getNode() + "sending to: " + recipient); if (links.isCheckwhois()) { String unknown = connections.get(nodeToIndex(recipient)).getHostname(); queue.add(new TaskMessage(c, -1, links, unknown)); } else { queue.add(new TaskMessage(c, -1, links, recipient, texts.get(i))); } } } } } }
@Override protected void sendRequest( Connection connection, long requestId, String action, TransportRequest request, TransportRequestOptions options) throws IOException { if (recoveryActionToBlock.equals(action) || requestBlocked.getCount() == 0) { logger.info("--> preventing {} request", action); requestBlocked.countDown(); if (dropRequests) { return; } throw new ConnectTransportException( connection.getNode(), "DISCONNECT: prevented " + action + " request"); } super.sendRequest(connection, requestId, action, request, options); }
@Override public void run() { try { while (true) { synchronized (queue) { sendNow(queue); } int l = connections.size(); for (int i = 0; i < l; i++) { Connection c = connections.get(i); if (c != null && c.ready()) { JsonObject message = c.read(); if (message != null) { route(message, c.getNode()); } } } Thread.sleep(1000L); // System.out.print('+'); } } catch (InterruptedException e) { System.out.println("Closing server!"); } }