/** * Adds the given <code>Contact</code> or updates it if it's already in our <code>RouteTable * </code> */ private synchronized void addLiveContactInfo(Contact node, DHTMessage message) { RouteTable routeTable = context.getRouteTable(); // If the Node is going to shutdown then don't bother // further than this. if (node.isShutdown()) { if (LOG.isInfoEnabled()) { LOG.info(node + " is going to shut down"); } synchronized (routeTable) { // Make sure there's an existing Contact in the RouteTable. // Otherwise don't bother! Contact existing = routeTable.get(node.getNodeID()); if (node.equals(existing)) { // Update the new Contact in the RouteTable and // mark it as shutdown // mark the existing contact as shutdown if its alive or // it will not be removed. if (existing.isAlive()) existing.shutdown(true); routeTable.add(node); node.shutdown(true); } } return; } // Ignore firewalled Nodes if (node.isFirewalled()) { if (LOG.isInfoEnabled()) { LOG.info(node + " is firewalled"); } return; } if (ContactUtils.isPrivateAddress(node)) { if (LOG.isInfoEnabled()) { LOG.info(node + " has a private address"); } return; } KUID nodeId = node.getNodeID(); if (context.isLocalNodeID(nodeId)) { // This is expected if there's a Node ID collision assert (message instanceof PingResponse) : "Expected a PingResponse but got a " + message.getClass() + " from " + message.getContact(); if (LOG.isInfoEnabled()) { LOG.info("Looks like our NodeID collides with " + node); } return; } if (StoreSettings.STORE_FORWARD_ENABLED.getValue()) { // Only do store forward if it is a new node in our routing table // (we are (re)connecting to the network) or a node that is reconnecting Contact existing = routeTable.get(nodeId); if (existing == null || existing.isDead() || existing.getInstanceID() != node.getInstanceID()) { // Store forward only if we're bootstrapped if (context.isBootstrapped()) { int k = KademliaSettings.REPLICATION_PARAMETER.getValue(); // we select the 2*k closest nodes in order to also check those values // where the local node is part of the k closest to the value but not part // of the k closest to the new joining node. Collection<Contact> nodes = routeTable.select(nodeId, 2 * k, SelectMode.ALL); // Are we one of the K nearest Nodes to the contact? if (containsNodeID(nodes, context.getLocalNodeID())) { if (LOG.isTraceEnabled()) { LOG.trace( "Node " + node + " is new or has changed his instanceID, will check for store forward!"); } forwardOrRemoveValues(node, existing, message); } } } } // Add the Node to our RouteTable or if it's // already there update its timeStamp and whatsoever routeTable.add(node); }
@Before public void setUp() { NetworkSettings.LOCAL_IS_PRIVATE.setValue(false); NetworkSettings.FILTER_CLASS_C.setValue(false); ContactUtils.setNetworkInstanceUtils(new SimpleNetworkInstanceUtils(false)); }