From 3508d88ba13649fd45130b72122a02fdd0506434 Mon Sep 17 00:00:00 2001 From: Caleb James DeLisle Date: Sun, 26 Mar 2017 23:17:49 +0200 Subject: [PATCH] Make sure to use a better metric for new pathfinder stuff so that the old pathfinder doesn't evict it --- dht/Pathfinder.c | 2 +- net/SessionManager.c | 70 +++++++++++++++++++++---------------- net/SessionManager.h | 2 ++ subnode/SubnodePathfinder.c | 60 +++++++++++++------------------ 4 files changed, 66 insertions(+), 68 deletions(-) diff --git a/dht/Pathfinder.c b/dht/Pathfinder.c index 0e6cb1a7d..7eaa89456 100644 --- a/dht/Pathfinder.c +++ b/dht/Pathfinder.c @@ -124,7 +124,7 @@ static void nodeForAddress(struct PFChan_Node* nodeOut, struct Address* addr, ui { Bits_memset(nodeOut, 0, PFChan_Node_SIZE); nodeOut->version_be = Endian_hostToBigEndian32(addr->protocolVersion); - nodeOut->metric_be = Endian_hostToBigEndian32(metric); + nodeOut->metric_be = Endian_hostToBigEndian32(metric | 0xffff0000); nodeOut->path_be = Endian_hostToBigEndian64(addr->path); Bits_memcpy(nodeOut->publicKey, addr->key, 32); Bits_memcpy(nodeOut->ip6, addr->ip6.bytes, 16); diff --git a/net/SessionManager.c b/net/SessionManager.c index 6f1082204..a11f0d825 100644 --- a/net/SessionManager.c +++ b/net/SessionManager.c @@ -199,12 +199,32 @@ static struct SessionManager_Session_pvt* getSession(struct SessionManager_pvt* uint8_t ip6[16], uint8_t pubKey[32], uint32_t version, - uint64_t label) + uint64_t label, + uint32_t metric) { struct SessionManager_Session_pvt* sess = sessionForIp6(ip6, sm); if (sess) { sess->pub.version = (sess->pub.version) ? sess->pub.version : version; - sess->pub.sendSwitchLabel = (sess->pub.sendSwitchLabel) ? sess->pub.sendSwitchLabel : label; + if (metric == 0xffffffff) { + // this is a broken path + if (sess->pub.sendSwitchLabel == label) { + debugSession0(sm->log, sess, "broken path"); + if (sess->pub.sendSwitchLabel == sess->pub.recvSwitchLabel) { + sess->pub.sendSwitchLabel = 0; + sess->pub.metric = 0xffffffff; + } else { + sess->pub.sendSwitchLabel = sess->pub.recvSwitchLabel; + sess->pub.metric = 0xfffffff0; + } + } + } else { + if (metric <= sess->pub.metric) { + sess->pub.sendSwitchLabel = label; + sess->pub.version = (version) ? version : sess->pub.version; + sess->pub.metric = metric; + debugSession0(sm->log, sess, "discovered path"); + } + } return sess; } struct Allocator* alloc = Allocator_child(sm->alloc); @@ -229,6 +249,7 @@ static struct SessionManager_Session_pvt* getSession(struct SessionManager_pvt* sess->pub.timeOfLastIn = Time_currentTimeMilliseconds(sm->eventBase); sess->pub.timeOfLastOut = Time_currentTimeMilliseconds(sm->eventBase); sess->pub.sendSwitchLabel = label; + sess->pub.metric = metric; //Allocator_onFree(alloc, sessionCleanup, sess); sendSession(sess, label, 0xffffffff, PFChan_Core_SESSION); check(sm, ifaceIndex); @@ -341,7 +362,7 @@ static Iface_DEFUN incomingFromSwitchIf(struct Message* msg, struct Iface* iface } uint64_t label = Endian_bigEndianToHost64(switchHeader->label_be); - session = getSession(sm, ip6, caHeader->publicKey, 0, label); + session = getSession(sm, ip6, caHeader->publicKey, 0, label, 0xfffff000); CryptoAuth_resetIfTimeout(session->pub.caSession); debugHandlesAndLabel(sm->log, session, label, "new session nonce[%d]", nonceOrHandle); } @@ -635,7 +656,8 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface header->ip6, header->publicKey, Endian_bigEndianToHost32(header->version_be), - Endian_bigEndianToHost64(header->sh.label_be)); + Endian_bigEndianToHost64(header->sh.label_be), + 0xfffffff0); } else { needsLookup(sm, msg, false); return NULL; @@ -698,33 +720,19 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* iface) Message_pop(msg, &node, PFChan_Node_SIZE, NULL); Assert_true(!msg->length); int index = Map_BufferedMessages_indexForKey((struct Ip6*)node.ip6, &sm->bufMap); - struct SessionManager_Session_pvt* sess; - if (index == -1) { - sess = sessionForIp6(node.ip6, sm); - // If we discovered a node we're not interested in ... - if (!sess) { return NULL; } - if (node.metric_be == 0xffffffff) { - // this is a broken path - if (sess->pub.sendSwitchLabel == Endian_bigEndianToHost64(node.path_be)) { - debugSession0(sm->log, sess, "broken path"); - if (sess->pub.sendSwitchLabel == sess->pub.recvSwitchLabel) { - sess->pub.sendSwitchLabel = 0; - } else { - sess->pub.sendSwitchLabel = sess->pub.recvSwitchLabel; - } - } - } else { - sess->pub.sendSwitchLabel = Endian_bigEndianToHost64(node.path_be); - sess->pub.version = Endian_bigEndianToHost32(node.version_be); - debugSession0(sm->log, sess, "discovered path"); - } - } else { - sess = getSession(sm, - node.ip6, - node.publicKey, - Endian_bigEndianToHost32(node.version_be), - Endian_bigEndianToHost64(node.path_be)); - } + struct SessionManager_Session_pvt* sess = sessionForIp6(node.ip6, sm); + if (!sess) { + // Node we don't care about. + if (index == -1) { return NULL; } + // Broken path to a node we don't have a session for... + if (node.metric_be == 0xffffffff) { return NULL; } + } + sess = getSession(sm, + node.ip6, + node.publicKey, + Endian_bigEndianToHost32(node.version_be), + Endian_bigEndianToHost64(node.path_be), + Endian_bigEndianToHost32(node.metric_be)); // Send what's on the buffer... if (index > -1 && CryptoAuth_getState(sess->pub.caSession) >= CryptoAuth_State_RECEIVED_KEY) { diff --git a/net/SessionManager.h b/net/SessionManager.h index 53a2ae0a4..0725b2f71 100644 --- a/net/SessionManager.h +++ b/net/SessionManager.h @@ -107,6 +107,8 @@ struct SessionManager_Session /** The version of the other node. */ uint32_t version; + uint32_t metric; + /** The best known switch label for reaching this node. */ uint64_t sendSwitchLabel; diff --git a/subnode/SubnodePathfinder.c b/subnode/SubnodePathfinder.c index 395ee1200..c9a4b5a81 100644 --- a/subnode/SubnodePathfinder.c +++ b/subnode/SubnodePathfinder.c @@ -125,27 +125,16 @@ static Iface_DEFUN switchErr(struct Message* msg, struct SubnodePathfinder_pvt* 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); + if (path == pf->pub.snh->snodeAddr.path) { + uint8_t pathStr[20]; + AddrTools_printPath(pathStr, path); + int err = Endian_bigEndianToHost32(switchErr.ctrlErr.errorType_be); + Log_debug(pf->log, "switch err from active snode [%s] type [%s][%d]", + pathStr, Error_strerror(err), err); + pf->pub.snh->snodeIsReachable = false; } - 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; } @@ -157,13 +146,13 @@ static void getRouteReply(Dict* msg, struct Address* src, struct MsgCore_Promise Log_debug(pf->log, "GetRoute timeout"); return; } - Log_debug(pf->log, "\n\n\n\nSearch reply!\n\n\n\n"); + Log_debug(pf->log, "Search reply!"); struct Address_List* al = ReplySerializer_parse(src, msg, pf->log, false, prom->alloc); if (!al || al->length == 0) { return; } Log_debug(pf->log, "reply with[%s]", Address_toString(&al->elems[0], prom->alloc)->bytes); //NodeCache_discoverNode(pf->nc, &al->elems[0]); struct Message* msgToCore = Message_new(0, 512, prom->alloc); - Iface_CALL(sendNode, msgToCore, &al->elems[0], 0xfffffff0, PFChan_Pathfinder_NODE, pf); + Iface_CALL(sendNode, msgToCore, &al->elems[0], 0xfff00000, PFChan_Pathfinder_NODE, pf); } static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt* pf) @@ -173,12 +162,12 @@ static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt* Assert_true(!msg->length); uint8_t printedAddr[40]; AddrTools_printIp(printedAddr, addr); - Log_debug(pf->log, "\n\n\n\nSearch req [%s]\n\n\n\n", printedAddr); + Log_debug(pf->log, "Search req [%s]", printedAddr); if (!pf->pub.snh || !pf->pub.snh->snodeAddr.path) { return NULL; } if (!Bits_memcmp(pf->pub.snh->snodeAddr.ip6.bytes, addr, 16)) { - return sendNode(msg, &pf->pub.snh->snodeAddr, 0xfffffff0, PFChan_Pathfinder_NODE, pf); + return sendNode(msg, &pf->pub.snh->snodeAddr, 0xfff00000, PFChan_Pathfinder_NODE, pf); } struct MsgCore_Promise* qp = MsgCore_createQuery(pf->msgCore, 0, pf->alloc); @@ -190,7 +179,7 @@ static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt* Assert_true(pf->pub.snh->snodeAddr.ip6.bytes[0] == 0xfc); qp->target = &pf->pub.snh->snodeAddr; - Log_debug(pf->log, "\n\n--Sending getRoute to snode %s--\n\n", + Log_debug(pf->log, "Sending getRoute to snode %s", Address_toString(qp->target, qp->alloc)->bytes); Dict_putStringCC(dict, "sq", "gr", qp->alloc); String* src = String_newBinary(pf->myAddress->ip6.bytes, 16, qp->alloc); @@ -237,7 +226,7 @@ static Iface_DEFUN peer(struct Message* msg, struct SubnodePathfinder_pvt* pf) ReachabilityCollector_change(pf->pub.rc, &addr); - return sendNode(msg, &addr, 0xffffff00, PFChan_Pathfinder_NODE, pf); + return sendNode(msg, &addr, 0xfff00000, PFChan_Pathfinder_NODE, pf); } static Iface_DEFUN peerGone(struct Message* msg, struct SubnodePathfinder_pvt* pf) @@ -287,23 +276,23 @@ static Iface_DEFUN sessionEnded(struct Message* msg, struct SubnodePathfinder_pv static Iface_DEFUN discoveredPath(struct Message* msg, struct SubnodePathfinder_pvt* pf) { - struct Address addr; - addressForNode(&addr, msg); - Log_debug(pf->log, "discoveredPath(%s)", Address_toString(&addr, msg->alloc)->bytes); + //struct Address addr; + //addressForNode(&addr, msg); + //Log_debug(pf->log, "discoveredPath(%s)", Address_toString(&addr, msg->alloc)->bytes); //if (addr.protocolVersion) { NodeCache_discoverNode(pf->nc, &addr); } return NULL; } static Iface_DEFUN handlePing(struct Message* msg, struct SubnodePathfinder_pvt* pf) { - Log_debug(pf->log, "Received ping"); + //Log_debug(pf->log, "Received ping"); Message_push32(msg, PFChan_Pathfinder_PONG, NULL); return Iface_next(&pf->pub.eventIf, msg); } static Iface_DEFUN handlePong(struct Message* msg, struct SubnodePathfinder_pvt* pf) { - Log_debug(pf->log, "Received pong"); + //Log_debug(pf->log, "Received pong"); return NULL; } @@ -325,14 +314,13 @@ static void unsetupSessionPingReply(Dict* msg, struct Address* src, struct MsgCo struct SubnodePathfinder_pvt* pf = Identity_check((struct SubnodePathfinder_pvt*) prom->userData); if (!src) { - Log_debug(pf->log, "Ping timeout"); + //Log_debug(pf->log, "Ping timeout"); return; } - Log_debug(pf->log, "\n\n\n\nPING reply from [%s]!\n\n\n\n", - Address_toString(src, prom->alloc)->bytes); - //NodeCache_discoverNode(pf->nc, src); + //Log_debug(pf->log, "\n\n\n\nPING reply from [%s]!\n\n\n\n", + // Address_toString(src, prom->alloc)->bytes); struct Message* msgToCore = Message_new(0, 512, prom->alloc); - Iface_CALL(sendNode, msgToCore, src, 0xffffff70, PFChan_Pathfinder_NODE, pf); + Iface_CALL(sendNode, msgToCore, src, 0xfffffff0, PFChan_Pathfinder_NODE, pf); } static Iface_DEFUN unsetupSession(struct Message* msg, struct SubnodePathfinder_pvt* pf) @@ -357,8 +345,8 @@ static Iface_DEFUN unsetupSession(struct Message* msg, struct SubnodePathfinder_ Assert_true(addr.path); qp->target = Address_clone(&addr, qp->alloc); - Log_debug(pf->log, "unsetupSession sending ping to [%s]", - Address_toString(qp->target, qp->alloc)->bytes); + //Log_debug(pf->log, "unsetupSession sending ping to [%s]", + // Address_toString(qp->target, qp->alloc)->bytes); Dict_putStringCC(dict, "q", "pn", qp->alloc); BoilerplateResponder_addBoilerplate(pf->br, dict, &addr, qp->alloc);