static Iface_DEFUN switchErr(struct Message* msg, struct Pathfinder_pvt* pf) { struct PFChan_Core_SwitchErr switchErr; Message_pop(msg, &switchErr, PFChan_Core_SwitchErr_MIN_SIZE, NULL); uint64_t path = Endian_bigEndianToHost64(switchErr.sh.label_be); uint64_t pathAtErrorHop = Endian_bigEndianToHost64(switchErr.ctrlErr.cause.label_be); uint8_t pathStr[20]; AddrTools_printPath(pathStr, path); int err = Endian_bigEndianToHost32(switchErr.ctrlErr.errorType_be); Log_debug(pf->log, "switch err from [%s] type [%s][%d]", pathStr, Error_strerror(err), err); struct Node_Link* link = NodeStore_linkForPath(pf->nodeStore, path); uint8_t nodeAddr[16]; if (link) { Bits_memcpy(nodeAddr, link->child->address.ip6.bytes, 16); } NodeStore_brokenLink(pf->nodeStore, path, pathAtErrorHop); if (link) { // Don't touch the node again, it might be a dangling pointer SearchRunner_search(nodeAddr, 20, 3, pf->searchRunner, pf->alloc); } return NULL; }
static Iface_DEFUN peer(struct Message* msg, struct Pathfinder_pvt* pf) { struct Address addr; addressForNode(&addr, msg); String* str = Address_toString(&addr, msg->alloc); Log_debug(pf->log, "Peer [%s]", str->bytes); struct Node_Link* link = NodeStore_linkForPath(pf->nodeStore, addr.path); // It exists, it's parent is the self-node, and it's label is equal to the switchLabel. if (link && Node_getBestParent(link->child) && Node_getBestParent(link->child)->parent->address.path == 1 && Node_getBestParent(link->child)->cannonicalLabel == addr.path) { return NULL; } //RumorMill_addNode(pf->rumorMill, &addr); Router_sendGetPeers(pf->router, &addr, 0, 0, pf->alloc); return sendNode(msg, &addr, 0xffffff00, pf); }
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; }
struct Node_Link* Router_linkForPath(struct Router* r, uint64_t path) { struct Router_pvt* rr = Identity_check((struct Router_pvt*)r); return NodeStore_linkForPath(rr->nodeStore, path); }