From 79d5478c6d6fda36352f9c8a793f8e9b3fcbc96e Mon Sep 17 00:00:00 2001 From: Caleb James DeLisle Date: Thu, 30 Mar 2017 09:31:27 +0200 Subject: [PATCH] Make sure the new and old pathfinders will never try to answer requests for nodes older/newer than v20 --- dht/Pathfinder.c | 8 ++++++++ net/SessionManager.c | 11 +++++++---- subnode/SubnodePathfinder.c | 10 ++++++++++ wire/PFChan.h | 6 +++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/dht/Pathfinder.c b/dht/Pathfinder.c index 7eaa89456..c1ca86026 100644 --- a/dht/Pathfinder.c +++ b/dht/Pathfinder.c @@ -135,6 +135,11 @@ static Iface_DEFUN sendNode(struct Message* msg, uint32_t metric, struct Pathfinder_pvt* pf) { + if (addr->protocolVersion > 19) { + Log_debug(pf->log, "not sending [%s] because version new", + Address_toString(addr, msg->alloc)->bytes); + return NULL; + } Message_reset(msg); Message_shift(msg, PFChan_Node_SIZE, NULL); nodeForAddress((struct PFChan_Node*) msg->bytes, addr, metric); @@ -276,6 +281,9 @@ static Iface_DEFUN switchErr(struct Message* msg, struct Pathfinder_pvt* pf) static Iface_DEFUN searchReq(struct Message* msg, struct Pathfinder_pvt* pf) { + uint32_t version = Message_pop32(msg, NULL); + Message_pop32(msg, NULL); + if (version >= 20) { return NULL; } uint8_t addr[16]; Message_pop(msg, addr, 16, NULL); Assert_true(!msg->length); diff --git a/net/SessionManager.c b/net/SessionManager.c index df7874adc..8e6d83db7 100644 --- a/net/SessionManager.c +++ b/net/SessionManager.c @@ -470,10 +470,12 @@ static void unsetupSession(struct SessionManager_pvt* sm, struct SessionManager_ Allocator_free(eventAlloc); } -static void triggerSearch(struct SessionManager_pvt* sm, uint8_t target[16]) +static void triggerSearch(struct SessionManager_pvt* sm, uint8_t target[16], uint32_t version) { struct Allocator* eventAlloc = Allocator_child(sm->alloc); struct Message* eventMsg = Message_new(0, 512, eventAlloc); + Message_push32(eventMsg, version, NULL); + Message_push32(eventMsg, 0, NULL); Message_push(eventMsg, target, 16, NULL); Message_push32(eventMsg, 0xffffffff, NULL); Message_push32(eventMsg, PFChan_Core_SEARCH_REQ, NULL); @@ -500,9 +502,10 @@ static void checkTimedOutSessions(struct SessionManager_pvt* sm) if (now - sess->pub.lastSearchTime >= sm->pub.sessionSearchAfterMilliseconds) { // Session is not in idle state and requires a search // But we're only going to trigger one search per cycle. - if (searchTriggered) { continue; } + // Except for v20 because the snode will answer us. + if (searchTriggered && sess->pub.version < 20) { continue; } debugSession0(sm->log, sess, "triggering search"); - triggerSearch(sm, sess->pub.caSession->herIp6); + triggerSearch(sm, sess->pub.caSession->herIp6, sess->pub.version); sess->pub.lastSearchTime = now; searchTriggered = true; } else if (CryptoAuth_getState(sess->pub.caSession) < CryptoAuth_State_RECEIVED_KEY) { @@ -557,7 +560,7 @@ static void needsLookup(struct SessionManager_pvt* sm, struct Message* msg, bool Allocator_adopt(lookupAlloc, msg->alloc); Assert_true(Map_BufferedMessages_put((struct Ip6*)header->ip6, &buffered, &sm->bufMap) > -1); - triggerSearch(sm, header->ip6); + triggerSearch(sm, header->ip6, Endian_hostToBigEndian32(header->version_be)); } static Iface_DEFUN readyToSend(struct Message* msg, diff --git a/subnode/SubnodePathfinder.c b/subnode/SubnodePathfinder.c index c9a4b5a81..a26ed62ee 100644 --- a/subnode/SubnodePathfinder.c +++ b/subnode/SubnodePathfinder.c @@ -150,6 +150,13 @@ static void getRouteReply(Dict* msg, struct Address* src, struct MsgCore_Promise 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); + + if (al->elems[0].protocolVersion < 20) { + Log_debug(pf->log, "not sending [%s] because version is old", + Address_toString(&al->elems[0], prom->alloc)->bytes); + return; + } + //NodeCache_discoverNode(pf->nc, &al->elems[0]); struct Message* msgToCore = Message_new(0, 512, prom->alloc); Iface_CALL(sendNode, msgToCore, &al->elems[0], 0xfff00000, PFChan_Pathfinder_NODE, pf); @@ -157,6 +164,9 @@ static void getRouteReply(Dict* msg, struct Address* src, struct MsgCore_Promise static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt* pf) { + uint32_t version = Message_pop32(msg, NULL); + Message_pop32(msg, NULL); + if (version && version < 20) { return NULL; } uint8_t addr[16]; Message_pop(msg, addr, 16, NULL); Assert_true(!msg->length); diff --git a/wire/PFChan.h b/wire/PFChan.h index 716b874ef..5011ee4d4 100644 --- a/wire/PFChan.h +++ b/wire/PFChan.h @@ -302,8 +302,12 @@ enum PFChan_Core struct PFChan_Core_SearchReq { uint8_t ipv6[16]; + + uint32_t pad; + + uint32_t version_be; }; -#define PFChan_Core_SearchReq_SIZE 16 +#define PFChan_Core_SearchReq_SIZE 24 Assert_compileTime(sizeof(struct PFChan_Core_SearchReq) == PFChan_Core_SearchReq_SIZE); struct PFChan_Core_Pathfinder