Exemplo n.º 1
0
static void searchReplyCallback(struct RouterModule_Promise* promise,
                                uint32_t lagMilliseconds,
                                struct Address* from,
                                Dict* result)
{
    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;
        }

        if (Address_closest(&search->target, &nodeList->elems[i], from) >= 0) {
            // Too much noise.
            //Log_debug(search->runner->logger, "Answer was further from the target than us.\n");
            continue;
        }

        if (search->lastNodeAsked.path != from->path) {
            // old queries coming in late...
            continue;
        }

        struct Node_Two* nn =
            NodeStore_getBest(search->runner->nodeStore, nodeList->elems[i].ip6.bytes);

        if (!nn) {
            RumorMill_addNode(search->runner->rumorMill, &nodeList->elems[i]);
        }

        //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);
    }
}
Exemplo n.º 2
0
static void onPingResponse(struct SwitchPinger_Response* resp, void* onResponseContext)
{
    if (SwitchPinger_Result_OK != resp->res) {
        return;
    }
    struct InterfaceController_Peer* ep =
        Identity_check((struct InterfaceController_Peer*) onResponseContext);
    struct InterfaceController_pvt* ic = ifcontrollerForPeer(ep);

    struct Address addr;
    Bits_memset(&addr, 0, sizeof(struct Address));
    Bits_memcpyConst(addr.key, CryptoAuth_getHerPublicKey(ep->cryptoAuthIf), 32);
    addr.path = ep->switchLabel;
    addr.protocolVersion = resp->version;

    #ifdef Log_DEBUG
        uint8_t addrStr[60];
        Address_print(addrStr, &addr);
        uint8_t key[56];
        Base32_encode(key, 56, CryptoAuth_getHerPublicKey(ep->cryptoAuthIf), 32);
    #endif

    if (!Version_isCompatible(Version_CURRENT_PROTOCOL, resp->version)) {
        Log_debug(ic->logger, "got switch pong from node [%s] with incompatible version [%d]",
                  key, resp->version);
    } else {
        Log_debug(ic->logger, "got switch pong from node [%s] with version [%d]",
                  key, resp->version);
    }

    if (!ep->timeOfLastPing) {
        // We've never heard from this machine before (or we've since forgotten about it)
        // This is here because we want the tests to function without the janitor present.
        // Other than that, it just makes a slightly more synchronous/guaranteed setup.
        Router_sendGetPeers(ic->router, &addr, 0, 0, ic->allocator);
    }

    struct Node_Link* link = Router_linkForPath(ic->router, resp->label);
    if (!link || !Node_getBestParent(link->child)) {
        RumorMill_addNode(ic->rumorMill, &addr);
    } else {
        Log_debug(ic->logger, "link exists");
    }

    ep->timeOfLastPing = Time_currentTimeMilliseconds(ic->eventBase);

    #ifdef Log_DEBUG
        // This will be false if it times out.
        //Assert_true(label == ep->switchLabel);
        uint8_t path[20];
        AddrTools_printPath(path, resp->label);
        uint8_t sl[20];
        AddrTools_printPath(sl, ep->switchLabel);
        Log_debug(ic->logger, "Received [%s] from lazy endpoint [%s]  [%s]",
                  SwitchPinger_resultString(resp->res)->bytes, path, sl);
    #endif
}
Exemplo n.º 3
0
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;
}