From ab6850bbe991fccfd6c4f1deb0bad984235b6f42 Mon Sep 17 00:00:00 2001 From: Caleb James DeLisle Date: Sun, 19 Mar 2017 19:20:30 +0100 Subject: [PATCH] Added a new message type to indicate when a path is known but the crypto session is not setup and handled this in the new pathfinder --- dht/Pathfinder.c | 1 + net/EventEmitter.c | 3 +- net/SessionManager.c | 31 +++++++++++++++--- subnode/SubnodePathfinder.c | 63 +++++++++++++++++++++++++++---------- wire/PFChan.h | 9 +++++- 5 files changed, 84 insertions(+), 23 deletions(-) diff --git a/dht/Pathfinder.c b/dht/Pathfinder.c index 2b13729f6..0e6cb1a7d 100644 --- a/dht/Pathfinder.c +++ b/dht/Pathfinder.c @@ -442,6 +442,7 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventI case PFChan_Core_MSG: return incomingMsg(msg, pf); case PFChan_Core_PING: return handlePing(msg, pf); case PFChan_Core_PONG: return handlePong(msg, pf); + case PFChan_Core_UNSETUP_SESSION: case PFChan_Core_CTRL_MSG: return NULL; default:; } diff --git a/net/EventEmitter.c b/net/EventEmitter.c index c6465a8ab..9665b58bc 100644 --- a/net/EventEmitter.c +++ b/net/EventEmitter.c @@ -147,6 +147,7 @@ static bool PFChan_Core_sizeOk(enum PFChan_Core ev, int size) case PFChan_Core_SESSION: case PFChan_Core_SESSION_ENDED: case PFChan_Core_DISCOVERED_PATH: + case PFChan_Core_UNSETUP_SESSION: return (size == 8 + PFChan_Node_SIZE); case PFChan_Core_MSG: @@ -165,7 +166,7 @@ static bool PFChan_Core_sizeOk(enum PFChan_Core ev, int size) } // Remember to add the event to this function too! Assert_compileTime(PFChan_Core__TOO_LOW == 1023); -Assert_compileTime(PFChan_Core__TOO_HIGH == 1038); +Assert_compileTime(PFChan_Core__TOO_HIGH == 1039); static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* trickIf) { diff --git a/net/SessionManager.c b/net/SessionManager.c index ff16625ca..d30d66e9c 100644 --- a/net/SessionManager.c +++ b/net/SessionManager.c @@ -419,6 +419,22 @@ static void checkTimedOutBuffers(struct SessionManager_pvt* sm) } } +static void unsetupSession(struct SessionManager_pvt* sm, struct SessionManager_Session_pvt* sess) +{ + struct Allocator* eventAlloc = Allocator_child(sm->alloc); + struct Message* eventMsg = Message_new(0, 512, eventAlloc); + struct PFChan_Node n; + n.path_be = Endian_hostToBigEndian64(sess->pub.sendSwitchLabel); + n.version_be = Endian_hostToBigEndian32(sess->pub.version); + Bits_memcpy(n.publicKey, sess->pub.caSession->herPublicKey, 32); + Bits_memcpy(n.ip6, sess->pub.caSession->herIp6, 16); + Message_push(eventMsg, &n, PFChan_Node_SIZE, NULL); + Message_push32(eventMsg, 0xffffffff, NULL); + Message_push32(eventMsg, PFChan_Core_UNSETUP_SESSION, NULL); + Iface_send(&sm->eventIf, eventMsg); + Allocator_free(eventAlloc); +} + static void triggerSearch(struct SessionManager_pvt* sm, uint8_t target[16]) { struct Allocator* eventAlloc = Allocator_child(sm->alloc); @@ -458,6 +474,9 @@ static void checkTimedOutSessions(struct SessionManager_pvt* sm) triggerSearch(sm, sess->pub.caSession->herIp6); sess->pub.lastSearchTime = now; searchTriggered = true; + } else if (CryptoAuth_getState(sess->pub.caSession) < CryptoAuth_State_RECEIVED_KEY) { + debugSession0(sm->log, sess, "triggering unsetupSession"); + unsetupSession(sm, sess); } } } @@ -469,7 +488,7 @@ static void periodically(void* vSessionManager) checkTimedOutBuffers(sm); } -static void needsLookup(struct SessionManager_pvt* sm, struct Message* msg) +static void needsLookup(struct SessionManager_pvt* sm, struct Message* msg, bool setupSession) { Assert_true(msg->length >= (RouteHeader_SIZE + DataHeader_SIZE)); struct RouteHeader* header = (struct RouteHeader*) msg->bytes; @@ -608,7 +627,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface Endian_bigEndianToHost32(header->version_be), Endian_bigEndianToHost64(header->sh.label_be)); } else { - needsLookup(sm, msg); + needsLookup(sm, msg, false); return NULL; } } @@ -616,7 +635,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface if (header->version_be) { sess->pub.version = Endian_bigEndianToHost32(header->version_be); } if (!sess->pub.version) { - needsLookup(sm, msg); + needsLookup(sm, msg, false); return NULL; } @@ -627,7 +646,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface header->sh.label_be = Endian_hostToBigEndian64(sess->pub.sendSwitchLabel); SwitchHeader_setVersion(&header->sh, SwitchHeader_CURRENT_VERSION); } else { - needsLookup(sm, msg); + needsLookup(sm, msg, false); return NULL; } @@ -636,7 +655,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface if (DataHeader_getContentType(dataHeader) != ContentType_CJDHT && CryptoAuth_getState(sess->pub.caSession) < CryptoAuth_State_RECEIVED_KEY) { - needsLookup(sm, msg); + needsLookup(sm, msg, true); return NULL; } @@ -703,6 +722,8 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* iface) Iface_CALL(readyToSend, bm->msg, sm, sess); Map_BufferedMessages_remove(index, &sm->bufMap); Allocator_free(bm->alloc); + } else if (CryptoAuth_getState(sess->pub.caSession) < CryptoAuth_State_RECEIVED_KEY) { + unsetupSession(sm, sess); } return NULL; } diff --git a/subnode/SubnodePathfinder.c b/subnode/SubnodePathfinder.c index e6f16ccbc..54f2256c5 100644 --- a/subnode/SubnodePathfinder.c +++ b/subnode/SubnodePathfinder.c @@ -165,21 +165,6 @@ static void getRouteReply(Dict* msg, struct Address* src, struct MsgCore_Promise struct Message* msgToCore = Message_new(0, 512, prom->alloc); Iface_CALL(sendNode, msgToCore, &al->elems[0], 0xfffffff0, PFChan_Pathfinder_NODE, pf); } -/* -static void pingReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom) -{ - struct SubnodePathfinder_pvt* pf = - Identity_check((struct SubnodePathfinder_pvt*) prom->userData); - if (!src) { - 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); - struct Message* msgToCore = Message_new(0, 512, prom->alloc); - Iface_CALL(sendNode, msgToCore, src, 0xffffff70, PFChan_Pathfinder_NODE, pf); -}*/ static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt* pf) { @@ -335,6 +320,51 @@ static Iface_DEFUN ctrlMsg(struct Message* msg, struct SubnodePathfinder_pvt* pf return Iface_next(&pf->switchPingerIf, msg); } +static void unsetupSessionPingReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom) +{ + struct SubnodePathfinder_pvt* pf = + Identity_check((struct SubnodePathfinder_pvt*) prom->userData); + if (!src) { + 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); + struct Message* msgToCore = Message_new(0, 512, prom->alloc); + Iface_CALL(sendNode, msgToCore, src, 0xffffff70, PFChan_Pathfinder_NODE, pf); +} + +static Iface_DEFUN unsetupSession(struct Message* msg, struct SubnodePathfinder_pvt* pf) +{ + struct PFChan_Node node; + Message_pop(msg, &node, PFChan_Node_SIZE, NULL); + Assert_true(!msg->length); + struct Address addr = { .protocolVersion = 0 }; + Bits_memcpy(addr.ip6.bytes, node.ip6, 16); + Bits_memcpy(addr.key, node.publicKey, 32); + addr.protocolVersion = Endian_bigEndianToHost32(node.version_be); + addr.path = Endian_bigEndianToHost64(node.path_be); + + // We have a path to the node but the session is not setup, lets ping them... + struct MsgCore_Promise* qp = MsgCore_createQuery(pf->msgCore, 0, pf->alloc); + + Dict* dict = qp->msg = Dict_new(qp->alloc); + qp->cb = unsetupSessionPingReply; + qp->userData = pf; + + Assert_true(addr.ip6.bytes[0] == 0xfc); + qp->target = Address_clone(&addr, qp->alloc); + + 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); + + return NULL; +} + static Iface_DEFUN incomingMsg(struct Message* msg, struct SubnodePathfinder_pvt* pf) { return Iface_next(&pf->msgCoreIf, msg); @@ -349,7 +379,7 @@ static Iface_DEFUN incomingFromMsgCore(struct Message* msg, struct Iface* iface) struct DataHeader* dh = (struct DataHeader*) &rh[1]; Assert_true(DataHeader_getContentType(dh) == ContentType_CJDHT); Assert_true(!Bits_isZero(rh->publicKey, 32)); - Assert_true(rh->version_be); + //Assert_true(rh->version_be); // Pinging peers can lead to not knowing their version... Assert_true(rh->sh.label_be); Message_push32(msg, PFChan_Pathfinder_SENDMSG, NULL); return Iface_next(&pf->pub.eventIf, msg); @@ -376,6 +406,7 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventI case PFChan_Core_PING: return handlePing(msg, pf); case PFChan_Core_PONG: return handlePong(msg, pf); case PFChan_Core_CTRL_MSG: return ctrlMsg(msg, pf); + case PFChan_Core_UNSETUP_SESSION: return unsetupSession(msg, pf); default:; } Assert_failure("unexpected event [%d]", ev); diff --git a/wire/PFChan.h b/wire/PFChan.h index 2f924b86c..716b874ef 100644 --- a/wire/PFChan.h +++ b/wire/PFChan.h @@ -289,7 +289,14 @@ enum PFChan_Core */ PFChan_Core_CTRL_MSG = 1037, - PFChan_Core__TOO_HIGH = 1038, + /** + * Will be emitted when the core has a path to a node but the session is not setup. + * Structure is a PFChan_Node + * (emitted by: SessionManager.c) + */ + PFChan_Core_UNSETUP_SESSION = 1038, + + PFChan_Core__TOO_HIGH = 1039, }; struct PFChan_Core_SearchReq