static void searchReplyCallback(struct RouterModule_Promise* promise, uint32_t lagMilliseconds, struct Address* from, Dict* result) { struct SearchRunner_Search* search = Identity_check((struct SearchRunner_Search*)promise->userData); if (!Bits_memcmp(from->ip6.bytes, search->target.ip6.bytes, 16)) { search->numFinds++; } struct Address_List* nodeList = ReplySerializer_parse(from, result, search->runner->logger, true, promise->alloc); struct Address* best = NULL; for (int i = 0; nodeList && i < nodeList->length; i++) { if (isDuplicateEntry(nodeList, i)) { continue; } if (Address_closest(&search->target, &nodeList->elems[i], from) >= 0) { // Too much noise. //Log_debug(search->runner->logger, "Answer was further from the target than us.\n"); continue; } if (search->lastNodeAsked.path != from->path) { // old queries coming in late... continue; } struct Node_Two* nn = NodeStore_getBest(search->runner->nodeStore, nodeList->elems[i].ip6.bytes); if (!nn) { RumorMill_addNode(search->runner->rumorMill, &nodeList->elems[i]); } //nodeList->elems[i].path = // NodeStore_optimizePath(search->runner->nodeStore, nodeList->elems[i].path); if (!Bits_memcmp(nodeList->elems[i].ip6.bytes, search->target.ip6.bytes, 16)) { if (!best) { best = &nodeList->elems[i]; continue; } else if (nodeList->elems[i].path < best->path) { SearchStore_addNodeToSearch(best, search->search); best = &nodeList->elems[i]; continue; } } SearchStore_addNodeToSearch(&nodeList->elems[i], search->search); } if (best) { SearchStore_addNodeToSearch(best, search->search); } }
static void onPingResponse(struct SwitchPinger_Response* resp, void* onResponseContext) { if (SwitchPinger_Result_OK != resp->res) { return; } struct InterfaceController_Peer* ep = Identity_check((struct InterfaceController_Peer*) onResponseContext); struct InterfaceController_pvt* ic = ifcontrollerForPeer(ep); struct Address addr; Bits_memset(&addr, 0, sizeof(struct Address)); Bits_memcpyConst(addr.key, CryptoAuth_getHerPublicKey(ep->cryptoAuthIf), 32); addr.path = ep->switchLabel; addr.protocolVersion = resp->version; #ifdef Log_DEBUG uint8_t addrStr[60]; Address_print(addrStr, &addr); uint8_t key[56]; Base32_encode(key, 56, CryptoAuth_getHerPublicKey(ep->cryptoAuthIf), 32); #endif if (!Version_isCompatible(Version_CURRENT_PROTOCOL, resp->version)) { Log_debug(ic->logger, "got switch pong from node [%s] with incompatible version [%d]", key, resp->version); } else { Log_debug(ic->logger, "got switch pong from node [%s] with version [%d]", key, resp->version); } if (!ep->timeOfLastPing) { // We've never heard from this machine before (or we've since forgotten about it) // This is here because we want the tests to function without the janitor present. // Other than that, it just makes a slightly more synchronous/guaranteed setup. Router_sendGetPeers(ic->router, &addr, 0, 0, ic->allocator); } struct Node_Link* link = Router_linkForPath(ic->router, resp->label); if (!link || !Node_getBestParent(link->child)) { RumorMill_addNode(ic->rumorMill, &addr); } else { Log_debug(ic->logger, "link exists"); } ep->timeOfLastPing = Time_currentTimeMilliseconds(ic->eventBase); #ifdef Log_DEBUG // This will be false if it times out. //Assert_true(label == ep->switchLabel); uint8_t path[20]; AddrTools_printPath(path, resp->label); uint8_t sl[20]; AddrTools_printPath(sl, ep->switchLabel); Log_debug(ic->logger, "Received [%s] from lazy endpoint [%s] [%s]", SwitchPinger_resultString(resp->res)->bytes, path, sl); #endif }
static Iface_DEFUN discoveredPath(struct Message* msg, struct Pathfinder_pvt* pf) { struct Address addr; addressForNode(&addr, msg); // We're somehow aware of this path (even if it's unused) if (NodeStore_linkForPath(pf->nodeStore, addr.path)) { return NULL; } // If we don't already care about the destination, then don't do anything. struct Node_Two* nn = NodeStore_nodeForAddr(pf->nodeStore, addr.ip6.bytes); if (!nn) { return NULL; } // Our best path is "shorter" (label bits which is somewhat representitive of hop count) // basically this is just to dampen the flood to the RM because otherwise it prevents Janitor // from getting any actual work done. if (nn->address.path < addr.path) { return NULL; } Log_debug(pf->log, "Discovered path [%s]", Address_toString(&addr, msg->alloc)->bytes); RumorMill_addNode(pf->rumorMill, &addr); return NULL; }