Explorar o código

it all seems to work well enough

Caleb James DeLisle %!s(int64=9) %!d(string=hai) anos
pai
achega
258a2c4a46

+ 21 - 5
dht/Pathfinder.c

@@ -104,10 +104,10 @@ static int incomingFromDHT(struct DHTMessage* dmessage, void* vpf)
     if (dmessage->replyTo) {
         // see incomingMsg
         dmessage->replyTo->pleaseRespond = true;
-        Log_debug(pf->log, "send DHT reply");
+        //Log_debug(pf->log, "send DHT reply");
         return 0;
     }
-    Log_debug(pf->log, "send DHT request");
+    //Log_debug(pf->log, "send DHT request");
 
     Iface_send(&pf->eventIf, msg);
     return 0;
@@ -192,6 +192,16 @@ static void addressForNode(struct Address* addrOut, struct Message* msg)
     Bits_memcpyConst(addrOut->ip6.bytes, node.ip6, 16);
 }
 
+static void nodeForAddress(struct PFChan_Node* nodeOut, struct Address* addr, uint32_t metric)
+{
+    Bits_memset(nodeOut, 0, PFChan_Node_SIZE);
+    nodeOut->version_be = Endian_hostToBigEndian32(addr->protocolVersion);
+    nodeOut->metric_be = Endian_hostToBigEndian32(metric);
+    nodeOut->path_be = Endian_hostToBigEndian64(addr->path);
+    Bits_memcpyConst(nodeOut->publicKey, addr->key, 32);
+    Bits_memcpyConst(nodeOut->ip6, addr->ip6.bytes, 16);
+}
+
 static Iface_DEFUN switchErr(struct Message* msg, struct Pathfinder_pvt* pf)
 {
     struct PFChan_Core_SwitchErr switchErr;
@@ -214,7 +224,7 @@ static Iface_DEFUN searchReq(struct Message* msg, struct Pathfinder_pvt* pf)
     AddrTools_printIp(printedAddr, addr);
     Log_debug(pf->log, "Search req [%s]", printedAddr);
 
-    SearchRunner_search(addr, 20, pf->searchRunner, pf->alloc);
+    SearchRunner_search(addr, 20, 3, pf->searchRunner, pf->alloc);
     return NULL;
 }
 
@@ -297,11 +307,11 @@ static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf)
     Message_shift(msg, -(RouteHeader_SIZE + DataHeader_SIZE), NULL);
     Bits_memcpyConst(addr.ip6.bytes, hdr->ip6, 16);
     Bits_memcpyConst(addr.key, hdr->publicKey, 32);
-    addr.protocolVersion = Endian_bigEndianToHost32(hdr->version_be);
+    int version = addr.protocolVersion = Endian_bigEndianToHost32(hdr->version_be);
     addr.padding = 0;
     addr.path = Endian_bigEndianToHost64(hdr->sh.label_be);
 
-    Log_debug(pf->log, "Incoming DHT");
+    //Log_debug(pf->log, "Incoming DHT");
 
     struct DHTMessage dht = {
         .address = &addr,
@@ -314,6 +324,12 @@ static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf)
     if (dht.pleaseRespond) {
         // what a beautiful hack, see incomingFromDHT
         return Iface_next(&pf->eventIf, msg);
+    } else if (!version && addr.protocolVersion) {
+        Message_reset(msg);
+        Message_shift(msg, PFChan_Node_SIZE, NULL);
+        nodeForAddress((struct PFChan_Node*) msg->bytes, &addr, 0xfffffffe);
+        Message_push32(msg, PFChan_Pathfinder_NODE, NULL);
+        return Iface_next(&pf->eventIf, msg);
     }
 
     return NULL;

+ 1 - 1
dht/dhtcore/Janitor.c

@@ -137,7 +137,7 @@ static void search(uint8_t target[16], struct Janitor* janitor)
 
     struct Allocator* searchAlloc = Allocator_child(janitor->allocator);
     struct RouterModule_Promise* rp =
-        SearchRunner_search(target, -1, janitor->searchRunner, searchAlloc);
+        SearchRunner_search(target, -1, -1, janitor->searchRunner, searchAlloc);
 
     if (!rp) {
         Log_debug(janitor->logger, "SearchRunner_search() returned NULL, probably full.");

+ 0 - 6
dht/dhtcore/Router.c

@@ -56,12 +56,6 @@ void Router_brokenLink(struct Router* r, uint64_t path, uint64_t labelAtErrorHop
     NodeStore_brokenLink(rr->nodeStore, path, labelAtErrorHop);
 }
 
-void Router_searchForNode(struct Router* r, uint8_t ip6[16], struct Allocator* alloc)
-{
-    struct Router_pvt* rr = Identity_check((struct Router_pvt*)r);
-    SearchRunner_search(ip6, -1, rr->searchRunner, alloc);
-}
-
 void Router_disconnectedPeer(struct Router* r, uint64_t path)
 {
     struct Router_pvt* rr = Identity_check((struct Router_pvt*)r);

+ 0 - 2
dht/dhtcore/Router.h

@@ -41,8 +41,6 @@ struct Node_Two* Router_lookup(struct Router* r, uint8_t targetAddr[16]);
 
 void Router_brokenLink(struct Router* r, uint64_t path, uint64_t labelAtErrorHop);
 
-void Router_searchForNode(struct Router* r, uint8_t ip6[16], struct Allocator* alloc);
-
 void Router_disconnectedPeer(struct Router* r, uint64_t path);
 
 struct Node_Link* Router_linkForPath(struct Router* r, uint64_t path);

+ 48 - 27
dht/dhtcore/SearchRunner.c

@@ -28,9 +28,6 @@
 #include "util/events/Timeout.h"
 #include "util/version/Version.h"
 
-/** The maximum number of requests to make before calling a search failed. */
-#define DEFAULT_MAX_REQUESTS_PER_SEARCH 8
-
 struct SearchRunner_pvt
 {
     struct SearchRunner pub;
@@ -72,6 +69,10 @@ struct SearchRunner_Search
     /** Maximum number of requests to make before terminating the search. */
     uint32_t maxRequests;
 
+    uint32_t maxRequestsIfFound;
+
+    uint32_t numFinds;
+
     /** The address which we are searching for. */
     struct Address target;
 
@@ -131,9 +132,15 @@ static void searchReplyCallback(struct RouterModule_Promise* promise,
     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;
@@ -157,10 +164,25 @@ static void searchReplyCallback(struct RouterModule_Promise* promise,
             RumorMill_addNode(search->runner->rumorMill, &nodeList->elems[i]);
         }
 
-        nodeList->elems[i].path =
-            NodeStore_optimizePath(search->runner->nodeStore, nodeList->elems[i].path);
+        //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 searchCallback(struct RouterModule_Promise* promise,
@@ -189,37 +211,31 @@ static void searchStep(struct SearchRunner_Search* search)
 {
     struct SearchRunner_pvt* ctx = Identity_check((struct SearchRunner_pvt*)search->runner);
 
-    struct Node_Two* node;
     struct SearchStore_Node* nextSearchNode;
     for (;;) {
         nextSearchNode = SearchStore_getNextNode(search->search);
 
         // If the number of requests sent has exceeded the max search requests, let's stop there.
-        if (search->totalRequests >= search->maxRequests || nextSearchNode == NULL) {
-            if (search->pub.callback) {
-                search->pub.callback(&search->pub, 0, NULL, NULL);
-            }
-            Allocator_free(search->pub.alloc);
-            return;
+        if (search->totalRequests >= search->maxRequests) {
+            // fallthrough
+        } else if (search->numFinds > 0 && search->totalRequests >= search->maxRequestsIfFound) {
+            // fallthrough
+        } else if (nextSearchNode == NULL) {
+            // fallthrough
+        } else {
+            break;
         }
-
-        node = NodeStore_getBest(ctx->nodeStore, nextSearchNode->address.ip6.bytes);
-
-        if (!node) { continue; }
-        if (node == ctx->nodeStore->selfNode) { continue; }
-        if (Bits_memcmp(node->address.ip6.bytes, nextSearchNode->address.ip6.bytes, 16)) {
-            continue;
+        if (search->pub.callback) {
+            search->pub.callback(&search->pub, 0, NULL, NULL);
         }
-
-        break;
+        Allocator_free(search->pub.alloc);
+        return;
     }
 
-    Assert_true(node != ctx->nodeStore->selfNode);
-
-    Bits_memcpyConst(&search->lastNodeAsked, &node->address, sizeof(struct Address));
+    Bits_memcpyConst(&search->lastNodeAsked, &nextSearchNode->address, sizeof(struct Address));
 
     struct RouterModule_Promise* rp =
-        RouterModule_newMessage(&node->address, 0, ctx->router, search->pub.alloc);
+        RouterModule_newMessage(&nextSearchNode->address, 0, ctx->router, search->pub.alloc);
 
     Dict* message = Dict_new(rp->alloc);
     Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_FN, rp->alloc);
@@ -285,6 +301,7 @@ struct SearchRunner_SearchData* SearchRunner_showActiveSearch(struct SearchRunne
 
 struct RouterModule_Promise* SearchRunner_search(uint8_t target[16],
                                                  int maxRequests,
+                                                 int maxRequestsIfFound,
                                                  struct SearchRunner* searchRunner,
                                                  struct Allocator* allocator)
 {
@@ -297,7 +314,10 @@ struct RouterModule_Promise* SearchRunner_search(uint8_t target[16],
     }
 
     if (maxRequests < 1) {
-        maxRequests = DEFAULT_MAX_REQUESTS_PER_SEARCH;
+        maxRequests = SearchRunner_DEFAULT_MAX_REQUESTS;
+    }
+    if (maxRequestsIfFound < 1) {
+        maxRequestsIfFound = SearchRunner_DEFAULT_MAX_REQUESTS_IF_FOUND;
     }
 
     struct Allocator* alloc = Allocator_child(allocator);
@@ -330,7 +350,8 @@ struct RouterModule_Promise* SearchRunner_search(uint8_t target[16],
         },
         .runner = runner,
         .search = sss,
-        .maxRequests = maxRequests
+        .maxRequests = maxRequests,
+        .maxRequestsIfFound = maxRequestsIfFound
     }));
     Identity_set(search);
     runner->searches++;

+ 8 - 0
dht/dhtcore/SearchRunner.h

@@ -47,6 +47,12 @@ struct SearchRunner
 
 #define SearchRunner_DEFAULT_MAX_CONCURRENT_SEARCHES 30
 
+/** The maximum number of requests to make before calling a search failed. */
+#define SearchRunner_DEFAULT_MAX_REQUESTS 8
+
+/** If the search found something, the maximum number of requests to make before call it done. */
+#define SearchRunner_DEFAULT_MAX_REQUESTS_IF_FOUND 8
+
 /**
  * Start a search.
  * The returned promise will have it's callback called for each result of the search and
@@ -54,11 +60,13 @@ struct SearchRunner
  *
  * @param searchTarget the address to search for.
  * @param maxRequests the number of requests to make before terminating the search.
+ * @param maxRequestsIfFound maximum number of requests if a find has been made.
  * @param runner the search runner
  * @param alloc an allocator for the search, free this to cancel the search
  */
 struct RouterModule_Promise* SearchRunner_search(uint8_t target[16],
                                                  int maxRequests,
+                                                 int maxRequestsIfFound,
                                                  struct SearchRunner* searchRunner,
                                                  struct Allocator* allocator);
 

+ 1 - 1
dht/dhtcore/SearchRunner_admin.c

@@ -121,7 +121,7 @@ static void search(Dict* args, void* vctx, String* txid, struct Allocator* reqAl
     } else {
         struct Allocator* alloc = Allocator_child(ctx->allocator);
         struct Search* s = Allocator_calloc(alloc, sizeof(struct Search), 1);
-        s->promise = SearchRunner_search(addr, maxRequests, ctx->runner, alloc);
+        s->promise = SearchRunner_search(addr, maxRequests, maxRequests, ctx->runner, alloc);
         s->ctx = ctx;
         s->txid = String_clone(txid, alloc);
         s->alloc = alloc;

+ 1 - 1
net/ConverterV15.c

@@ -114,7 +114,7 @@ static Iface_DEFUN incomingFromUpperDistributorIf(struct Message* msg,
                             (uint8_t*) udp,
                             msg->length - RouteHeader_SIZE - Headers_IP6Header_SIZE);
 
-        Log_debug(conv->log, "Converted CJDHT->v15");
+        //Log_debug(conv->log, "Converted CJDHT->v15");
     }
 
     //Log_debug(conv->log, "send [%s]", Hex_print(ip6, 32, msg->alloc));

+ 5 - 1
net/InterfaceController.c

@@ -324,7 +324,6 @@ static void iciPing(struct InterfaceController_Iface_pvt* ici, struct InterfaceC
         bool unresponsive = (now > ep->timeOfLastMessage + ic->unresponsiveAfterMilliseconds);
         if (unresponsive) {
             // our link to the peer is broken...
-            sendPeer(0xffffffff, PFChan_Core_PEER_GONE, ep);
 
             // XXX(cjd): we need to tell the switch about this because packets to this if
             // should be responded to with error packets.
@@ -335,7 +334,10 @@ static void iciPing(struct InterfaceController_Iface_pvt* ici, struct InterfaceC
                 continue;
             }
 
+            sendPeer(0xffffffff, PFChan_Core_PEER_GONE, ep);
             ep->state = InterfaceController_PeerState_UNRESPONSIVE;
+            SwitchCore_setInterfaceState(&ep->switchIf,
+                                         SwitchCore_setInterfaceState_ifaceState_DOWN);
         }
 
         Log_debug(ic->logger,
@@ -396,6 +398,7 @@ static Iface_DEFUN receivedPostCryptoAuth(struct Message* msg,
     if (ep->state < InterfaceController_PeerState_ESTABLISHED) {
         // EP states track CryptoAuth states...
         ep->state = caState;
+        SwitchCore_setInterfaceState(&ep->switchIf, SwitchCore_setInterfaceState_ifaceState_UP);
 
         Bits_memcpyConst(ep->addr.key, ep->caSession->herPublicKey, 32);
         Address_getPrefix(&ep->addr);
@@ -430,6 +433,7 @@ static Iface_DEFUN receivedPostCryptoAuth(struct Message* msg,
         && caState == CryptoAuth_ESTABLISHED)
     {
         ep->state = InterfaceController_PeerState_ESTABLISHED;
+        SwitchCore_setInterfaceState(&ep->switchIf, SwitchCore_setInterfaceState_ifaceState_UP);
     } else {
         ep->timeOfLastMessage = Time_currentTimeMilliseconds(ic->eventBase);
     }

+ 6 - 1
net/SessionManager.c

@@ -441,7 +441,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface
 
     struct SessionManager_Session_pvt* sess = sessionForIp6(header->ip6, sm);
     if (!sess) {
-        if (!Bits_isZero(header->publicKey, 32)) {
+        if (!Bits_isZero(header->publicKey, 32) && header->version_be) {
             sess = getSession(sm,
                               header->ip6,
                               header->publicKey,
@@ -455,6 +455,11 @@ 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);
+        return NULL;
+    }
+
     if (header->sh.label_be) {
         // fallthrough
     } else if (sess->pub.sendSwitchLabel) {

+ 0 - 2
net/SessionManager_admin.c

@@ -54,9 +54,7 @@ static void getHandles(Dict* args, void* vcontext, String* txid, struct Allocato
     String* more = String_CONST("more");
     if (i < hList->length) {
         Dict_putInt(r, more, 1, alloc);
-        Assert_true(i > 0);
     }
-    Assert_true(i == List_size(list));
 
     Admin_sendMessage(r, txid, context->admin);
 

+ 18 - 0
switch/SwitchCore.c

@@ -41,6 +41,8 @@ struct SwitchInterface
 
     struct Allocator_OnFreeJob* onFree;
 
+    int state;
+
     Identity
 };
 
@@ -190,6 +192,13 @@ static Iface_DEFUN receiveMessage(struct Message* message, struct Iface* iface)
         return sendError(sourceIf, message, Error_MALFORMED_ADDRESS, core->logger);
     }
 
+    if (core->interfaces[destIndex].state == SwitchCore_setInterfaceState_ifaceState_DOWN &&
+        1 != sourceIndex)
+    {
+        DEBUG_SRC_DST(core->logger, "DROP packet because interface is down");
+        return sendError(sourceIf, message, Error_UNDELIVERABLE, core->logger);
+    }
+
     /*if (sourceIndex == destIndex && sourceIndex != 1) {
         DEBUG_SRC_DST(core->logger, "DROP Packet with redundant route.");
         return sendError(sourceIf, message, Error_LOOP_ROUTE, core->logger);
@@ -227,6 +236,13 @@ static int removeInterface(struct Allocator_OnFreeJob* job)
     return 0;
 }
 
+void SwitchCore_setInterfaceState(struct Iface* userIf, int ifaceState)
+{
+    struct SwitchInterface* sif = Identity_check((struct SwitchInterface*) userIf->connectedIf);
+    Assert_true(ifaceState == (ifaceState & 1));
+    sif->state = ifaceState;
+}
+
 void SwitchCore_swapInterfaces(struct Iface* userIf1, struct Iface* userIf2)
 {
     struct SwitchInterface* si1 = Identity_check((struct SwitchInterface*) userIf1->connectedIf);
@@ -271,6 +287,7 @@ int SwitchCore_addInterface(struct SwitchCore* switchCore,
     newIf->alloc = alloc;
     newIf->penalty = Penalty_new(alloc, core->eventBase, core->logger);
     newIf->onFree = Allocator_onFree(alloc, removeInterface, newIf);
+    newIf->state = SwitchCore_setInterfaceState_ifaceState_UP;
     Iface_plumb(iface, &newIf->iface);
 
     uint32_t bits = NumberCompress_bitsUsedForNumber(ifIndex);
@@ -294,6 +311,7 @@ struct SwitchCore* SwitchCore_new(struct Log* logger,
     routerIf->iface.send = receiveMessage;
     routerIf->core = core;
     routerIf->alloc = allocator;
+    routerIf->state = SwitchCore_setInterfaceState_ifaceState_UP;
     core->pub.routerIf = &routerIf->iface;
 
     return &core->pub;

+ 4 - 0
switch/SwitchCore.h

@@ -48,4 +48,8 @@ int SwitchCore_addInterface(struct SwitchCore* switchCore,
 
 void SwitchCore_swapInterfaces(struct Iface* if1, struct Iface* if2);
 
+#define SwitchCore_setInterfaceState_ifaceState_DOWN 0
+#define SwitchCore_setInterfaceState_ifaceState_UP   1
+void SwitchCore_setInterfaceState(struct Iface* iface, int ifaceState);
+
 #endif