Permalink
Browse files

Make sure nodes which have the wrong label because of a router reset …

…are eventually flushed out of the table
  • Loading branch information...
1 parent 9911136 commit 3b95ddb3cc45b06d3ffa48414cfab70900b77209 Caleb James DeLisle committed Mar 10, 2013
Showing with 26 additions and 25 deletions.
  1. +22 −23 dht/dhtcore/NodeStore.c
  2. +4 −2 dht/dhtcore/RouterModule.c
View
@@ -215,32 +215,31 @@ struct Node* NodeStore_addNode(struct NodeStore* store,
continue;
}
- /*#ifdef Log_DEBUG
- uint32_t oldReach = store->headers[i].reach;
- #endif*/
-
adjustReach(&store->headers[i], reachDifference, store);
+ store->headers[i].version = version;
+ return nodeForIndex(store, i);
- if (version) {
+ } else if (store->nodes[i].address.path == addr->path) {
+ // When a node restarts, it's switch renumbers meaning that the paths to other nodes
+ // change. This causes a previously valid path to A to now point to B. The problem
+ // is that there is a real node at the end of the path to B and worse, there are real
+ // nodes behind that one. When those nodes respond to pings and searches, their reach
+ // is updated along with the now-invalid node A.
+ // This will allow incoming packets from B to clear A out of the table and replace
+ // them with B while preventing another node's memory of B from causing A to be
+ // replaced.
+ if (reachDifference > 0) {
+ replaceNode(&store->nodes[i], &store->headers[i], addr, store);
+ store->headers[i].reach = reachDifference;
store->headers[i].version = version;
+ return nodeForIndex(store, i);
+ } else {
+ // TODO:
+ // We were told about another node, it might be B and it might be A (invalid).
+ // the only way to know for sure it to queue a ping to that node and wait for it
+ // to respond. We need a system for queueing pings so we don't send out a flood.
+ return NULL;
}
-
- /*#ifdef Log_DEBUG
- if (oldReach != store->headers[i].reach) {
- uint8_t nodeAddr[60];
- Address_print(nodeAddr, addr);
- Log_debug(store->logger,
- "Altering reach for node %s, old reach %u, new reach %u.\n",
- nodeAddr,
- oldReach,
- store->headers[i].reach);
- if (oldReach > store->headers[i].reach) {
- Log_debug(store->logger, "Reach was decreased!\n");
- }
- }
- #endif*/
-
- return nodeForIndex(store, i);
}
if (store->size >= store->capacity) {
@@ -411,7 +410,7 @@ void NodeStore_updateReach(const struct Node* const node,
}
}
} else if (LabelSplicer_routesThrough(path, dest)) {
- /* BUG:
+ /*
* When a switch restarts, it repopulates it's slots in random order.
* Nodes have stale entries in their tables that predate the switch restart.
* these entries contain valid keys with valid paths but the key does not match
@@ -714,7 +714,7 @@ static inline int handleReply(struct DHTMessage* message, struct RouterModule* m
// it probably means that we just flushed them from the table because
// a node further up the tree has become unresponsive.
// ignore their message because it would add orphaned entries to the node tree.
- struct Node* node = RouterModule_lookup(message->address->ip6.bytes, module);
+ struct Node* node = NodeStore_getNodeByNetworkAddr(message->address->path, module->nodeStore);
if (!node || Bits_memcmp(node->address.key, message->address->key, 32)) {
return 0;
}
@@ -723,7 +723,9 @@ static inline int handleReply(struct DHTMessage* message, struct RouterModule* m
uint32_t version = ((versionPtr) ? *versionPtr : 0);
// this implementation only pings to get the address of a node, so lets add the node.
- node = NodeStore_addNode(module->nodeStore, message->address, 0, version);
+ node = NodeStore_addNode(module->nodeStore, message->address, 2, version);
+
+ Assert_true(node);
String* tid = Dict_getString(message->asDict, CJDHTConstants_TXID);

0 comments on commit 3b95ddb

Please sign in to comment.