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); }
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); } }
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); }
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); }
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); } } } }
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); }