Exemplo n.º 1
0
static void genericResponse(struct RouterModule_Promise* promise,
                            uint32_t lag,
                            struct Address* from,
                            Dict* responseDict,
                            String* name)
{
    struct Ping* ping = Identity_check((struct Ping*)promise->userData);
    Dict* out = Dict_new(promise->alloc);
    String* result = (responseDict) ? name : String_CONST("timeout");
    Dict_putString(out, String_CONST("result"), result, promise->alloc);

    if (responseDict) {
        struct Address_List* addrs =
            ReplySerializer_parse(from, responseDict, NULL, promise->alloc);

        List* nodes = List_new(promise->alloc);
        for (int i = 0; i < addrs->length; i++) {
            String* addr = Address_toString(&addrs->elems[i], promise->alloc);
            List_addString(nodes, addr, promise->alloc);
        }
        Dict_putList(out, name, nodes, promise->alloc);
    }

    Dict_putInt(out, String_CONST("ms"), lag, promise->alloc);

    Dict_putString(out, String_CONST("error"), String_CONST("none"), promise->alloc);

    Admin_sendMessage(out, ping->txid, ping->ctx->admin);
}
Exemplo n.º 2
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.º 3
0
static void searchResponse(struct RouterModule_Promise* promise,
                           uint32_t lag,
                           struct Address* from,
                           Dict* responseDict)
{
    struct Search* search = Identity_check((struct Search*) promise->userData);
    struct Allocator* alloc = Allocator_child(search->alloc);

    Dict* resp = Dict_new(alloc);
    if (!from) {
        Dict_putStringCC(resp, "error", "none", alloc);
        Dict_putIntC(resp, "complete", 1, alloc);
        Admin_sendMessage(resp, search->txid, search->ctx->admin);
        Allocator_free(alloc);
        return;
    }

    String* fromStr = Address_toString(from, alloc);
    Dict_putStringC(resp, "from", fromStr, alloc);

    Dict_putIntC(resp, "ms", lag, alloc);

    struct Address_List* addrs = ReplySerializer_parse(from, responseDict, NULL, true, alloc);
    List* nodes = List_new(alloc);
    for (int i = 0; addrs && i < addrs->length; i++) {
        String* addr = Address_toString(&addrs->elems[i], alloc);
        List_addString(nodes, addr, alloc);
    }
    Dict_putListC(resp, "nodes", nodes, alloc);

    Admin_sendMessage(resp, search->txid, search->ctx->admin);
}
Exemplo n.º 4
0
static void onReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom)
{
    struct ReachabilityCollector_pvt* rcp =
        Identity_check((struct ReachabilityCollector_pvt*) prom->userData);
    Assert_true(prom == rcp->msgOnWire);
    if (!src) {
        onReplyTimeout(prom);
        mkNextRequest(rcp);
        return;
    }
    struct Address_List* results = ReplySerializer_parse(src, msg, rcp->log, false, prom->alloc);
    uint64_t path = 1;

    struct PeerInfo* pi = NULL;
    for (int j = 0; j < rcp->piList->length; j++) {
        struct PeerInfo* pi0 = ArrayList_OfPeerInfo_get(rcp->piList, j);
        if (Address_isSameIp(&pi0->addr, src)) {
            pi = pi0;
            break;
        }
    }
    if (!pi) {
        Log_debug(rcp->log, "Got message from peer which is gone from list");
        return;
    }

    for (int i = 0; i < results->length; i++) {
        path = results->elems[i].path;
        if (Bits_memcmp(results->elems[i].ip6.bytes, rcp->myAddr->ip6.bytes, 16)) { continue; }
        if (pi->pathThemToUs != path) {
            Log_debug(rcp->log, "Found back-route for [%s]",
                Address_toString(src, prom->alloc)->bytes);
            if (rcp->pub.onChange) {
                rcp->pub.onChange(
                    &rcp->pub, src->ip6.bytes, path, src->path, 0, 0xffff, 0xffff, 0xffff);
            }
        }
        pi->pathThemToUs = path;
        pi->querying = false;
        return;
    }
    pi->pathToCheck = (results->length < 8) ? 1 : path;
    mkNextRequest(rcp);
}
Exemplo n.º 5
0
static void onReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom)
{
    struct Query* q = Identity_check((struct Query*) prom->userData);
    struct SupernodeHunter_pvt* snp = Identity_check(q->snp);

    // TODO(cjd): if we sent a message to a discovered node, we should drop them from the list
    //            if we sent to one of snodeCandidates then we need to drop it from that list.
    if (!src) {
        String* addrStr = Address_toString(prom->target, prom->alloc);
        Log_debug(snp->log, "timeout sending to %s", addrStr->bytes);
        return;
    }
    String* addrStr = Address_toString(src, prom->alloc);
    Log_debug(snp->log, "Reply from %s", addrStr->bytes);

    int64_t* snodeRecvTime = Dict_getIntC(msg, "recvTime");

    if (q->isGetRoute) {
        //struct Address_List* al = ReplySerializer_parse(src, msg, snp->log, false, prom->alloc);
        if (!snodeRecvTime) {
            Log_warn(snp->log, "getRoute reply with no timeStamp, bad snode");
            return;
        }
        Log_debug(snp->log, "\n\nSupernode location confirmed [%s]\n\n",
            Address_toString(src, prom->alloc)->bytes);
        Bits_memcpy(&snp->pub.snodeAddr, src, Address_SIZE);
        if (snp->pub.snodeIsReachable) {
            // If while we were searching, the outside code declared that indeed the snode
            // is reachable, we will not try to change their snode.
        } else if (snp->pub.onSnodeChange) {
            snp->pub.snodeIsReachable = true;
            snp->pub.onSnodeChange(
                snp->pub.userData, &snp->pub.snodeAddr, q->sendTime, *snodeRecvTime);
        } else {
            Log_warn(snp->log, "onSnodeChange is not set");
        }
    }

    struct Address_List* results = ReplySerializer_parse(src, msg, snp->log, true, prom->alloc);
    if (!results) {
        Log_debug(snp->log, "reply without nodes");
        return;
    }
    for (int i = 0; i < results->length; i++) {
        if (!q->searchTar) {
            // This is a getPeers
            Log_debug(snp->log, "getPeers reply [%s]",
                Address_toString(&results->elems[i], prom->alloc)->bytes);
            if (Address_isSameIp(&results->elems[i], snp->myAddress)) { continue; }
            if (snp->nodes->length >= SupernodeHunter_pvt_nodes_MAX) { AddrSet_flush(snp->nodes); }
            AddrSet_add(snp->nodes, &results->elems[i]);
        } else {
            if (!Bits_memcmp(&results->elems[i].ip6.bytes, q->searchTar->ip6.bytes, 16)) {
                Log_debug(snp->log, "\n\nFound a supernode w000t [%s]\n\n",
                    Address_toString(&results->elems[i], prom->alloc)->bytes);
                if (snp->snodeCandidates->length >= SupernodeHunter_pvt_snodeCandidates_MAX) {
                    AddrSet_flush(snp->snodeCandidates);
                }
                AddrSet_add(snp->snodeCandidates, &results->elems[i]);
            } else {
                //Log_debug(snp->log, "findNode reply [%s] to discard",
                //    Address_toString(&results->elems[i], prom->alloc)->bytes);
            }
        }
    }
}
Exemplo n.º 6
0
static void onReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom)
{
    struct Query* q = (struct Query*) prom->userData;
    struct ReachabilityCollector_pvt* rcp =
        Identity_check((struct ReachabilityCollector_pvt*) q->rcp);
    if (!src) {
        onReplyTimeout(prom);
        mkNextRequest(rcp);
        return;
    }

    struct PeerInfo_pvt* pi = NULL;
    for (int j = 0; j < rcp->piList->length; j++) {
        struct PeerInfo_pvt* pi0 = ArrayList_OfPeerInfo_pvt_get(rcp->piList, j);
        if (Address_isSameIp(&pi0->pub.addr, src)) {
            pi = pi0;
            break;
        }
    }
    if (!pi) {
        Log_debug(rcp->log, "Got message from peer which is gone from list");
        return;
    }

    pi->waitForResponse = false;

    struct Address_List* results = ReplySerializer_parse(src, msg, rcp->log, false, prom->alloc);
    uint64_t path = 1;
    if (!results) {
        Log_debug(rcp->log, "Got invalid getPeers reply from [%s]",
            Address_toString(src, prom->alloc)->bytes);
        return;
    }
    for (int i = results->length - 1; i >= 0; i--) {
        path = results->elems[i].path;
        Log_debug(rcp->log, "getPeers result [%s] [%s][%s]",
            Address_toString(&results->elems[i], prom->alloc)->bytes,
            q->addr->bytes, q->targetPath);
        if (Bits_memcmp(results->elems[i].ip6.bytes, rcp->myAddr->ip6.bytes, 16)) { continue; }
        if (pi->pub.pathThemToUs != path) {
            Log_debug(rcp->log, "Found back-route for [%s]",
                Address_toString(src, prom->alloc)->bytes);
            pi->pub.pathThemToUs = path;
            if (rcp->pub.onChange) {
                rcp->pub.onChange(
                    &rcp->pub, src->ip6.bytes, path, src->path, 0, 0xffff, 0xffff, 0xffff);
            }
        }
        pi->pub.querying = false;
        mkNextRequest(rcp);
        return;
    }
    if (results->length < 8) {
        // Peer's gp response does not include my addr, meaning the peer might not know us yet.
        // should wait peer sendPing (see InterfaceControl.c).
        pi->pathToCheck = 1;
        return;
    } else {
        pi->pathToCheck = path;
    }
    mkNextRequest(rcp);
}