static void search(Dict* args, void* vctx, String* txid, struct Allocator* reqAlloc) { struct Context* ctx = Identity_check((struct Context*) vctx); String* addrStr = Dict_getStringC(args, "ipv6"); int maxRequests = -1; uint64_t* maxRequestsPtr = Dict_getIntC(args, "maxRequests"); if (maxRequestsPtr) { maxRequests = *maxRequestsPtr; } uint8_t addr[16]; if (AddrTools_parseIp(addr, (uint8_t*) addrStr->bytes)) { Dict* resp = Dict_new(reqAlloc); Dict_putStringCC(resp, "error", "ipv6 invalid", reqAlloc); Admin_sendMessage(resp, txid, ctx->admin); } else { struct Allocator* alloc = Allocator_child(ctx->allocator); struct Search* s = Allocator_calloc(alloc, sizeof(struct Search), 1); s->promise = SearchRunner_search(addr, maxRequests, maxRequests, ctx->runner, alloc); s->ctx = ctx; s->txid = String_clone(txid, alloc); s->alloc = alloc; Identity_set(s); if (!s->promise) { Dict* resp = Dict_new(reqAlloc); Dict_putStringCC(resp, "error", "creating search", reqAlloc); Admin_sendMessage(resp, txid, ctx->admin); Allocator_free(alloc); return; } s->promise->userData = s; s->promise->callback = searchResponse; } }
static void nodeInfo(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* const ctx = Identity_check((struct Context*) vcontext); String* myAddr = Address_toString(ctx->nc->myAddress, requestAlloc); String* schemeStr = EncodingScheme_serialize(ctx->encodingScheme, requestAlloc); List* schemeList = EncodingScheme_asList(ctx->encodingScheme, requestAlloc); Dict* out = Dict_new(requestAlloc); Dict_putStringC(out, "myAddr", myAddr, requestAlloc); char* schemeHex = Hex_print(schemeStr->bytes, schemeStr->len, requestAlloc); Dict_putStringCC(out, "compressedSchemeHex", schemeHex, requestAlloc); Dict_putListC(out, "encodingScheme", schemeList, requestAlloc); Dict_putIntC(out, "version", Version_CURRENT_PROTOCOL, requestAlloc); Dict_putStringCC(out, "error", "none", requestAlloc); Admin_sendMessage(out, txid, ctx->admin); }
static void adminDisconnectPeer(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*)vcontext); String* pubkeyString = Dict_getStringC(args, "pubkey"); // parse the key uint8_t pubkey[32]; uint8_t addr[16]; int error = Key_parse(pubkeyString, pubkey, addr); char* errorMsg = NULL; if (error) { errorMsg = "bad key"; } else { // try to remove the peer if the key is valid error = InterfaceController_disconnectPeer(context->ic,pubkey); if (error) { errorMsg = "no peer found for that key"; } } Dict* response = Dict_new(requestAlloc); Dict_putIntC(response, "success", error ? 0 : 1, requestAlloc); if (error) { Dict_putStringCC(response, "error", errorMsg, requestAlloc); } Admin_sendMessage(response, txid, context->admin); }
static void adminResetPeering(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*)vcontext); String* pubkeyString = Dict_getStringC(args, "pubkey"); int error = 0; char* errorMsg = NULL; if (pubkeyString) { // parse the key uint8_t pubkey[32]; uint8_t addr[16]; error = Key_parse(pubkeyString, pubkey, addr); if (error) { errorMsg = "bad key"; } else { InterfaceController_resetPeering(context->ic, pubkey); } } else { // reset all InterfaceController_resetPeering(context->ic, NULL); } Dict* response = Dict_new(requestAlloc); Dict_putIntC(response, "success", error ? 0 : 1, requestAlloc); if (error) { Dict_putStringCC(response, "error", errorMsg, requestAlloc); } Admin_sendMessage(response, txid, context->admin); }
static void adminInterfaces(Dict* args, void* vcontext, String* txid, struct Allocator* alloc) { struct Context* context = Identity_check((struct Context*)vcontext); int64_t* page = Dict_getIntC(args, "page"); int i = (page) ? *page * ENTRIES_PER_PAGE : 0; int count = InterfaceController_ifaceCount(context->ic); //int count = InterfaceController_getIface(context->ic, alloc, &stats); List* list = List_new(alloc); for (int counter = 0; i < count && counter++ < ENTRIES_PER_PAGE; i++) { struct InterfaceController_Iface* iface = InterfaceController_getIface(context->ic, i); Dict* d = Dict_new(alloc); Dict_putIntC(d, "ifNum", iface->ifNum, alloc); Dict_putStringC(d, "name", iface->name, alloc); char* bs = InterfaceController_beaconStateString(iface->beaconState); Dict_putStringCC(d, "beaconState", bs, alloc); List_addDict(list, d, alloc); } Dict* resp = Dict_new(alloc); Dict_putListC(resp, "ifaces", list, alloc); Dict_putIntC(resp, "total", count, alloc); if (i < count) { Dict_putIntC(resp, "more", 1, alloc); } Admin_sendMessage(resp, txid, context->admin); }
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 checkPermissionsB(struct Except* eh, String* txid, struct Admin* admin, struct Allocator* requestAlloc) { struct Security_Permissions* sp = Security_checkPermissions(requestAlloc, eh); Dict* out = Dict_new(requestAlloc); Dict_putIntC(out, "noOpenFiles", sp->noOpenFiles, requestAlloc); Dict_putIntC(out, "seccompExists", sp->seccompExists, requestAlloc); Dict_putIntC(out, "seccompEnforcing", sp->seccompEnforcing, requestAlloc); Dict_putIntC(out, "userId", sp->uid, requestAlloc); Dict_putStringCC(out, "error", "none", requestAlloc); Admin_sendMessage(out, txid, admin); }
static void timestampPackets(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*)vcontext); int64_t* enable = Dict_getIntC(args, "enable"); Dict* response = Dict_new(requestAlloc); Dict_putStringCC(response, "error", "none", requestAlloc); if (!enable) { Dict_putIntC(response, "enabled", context->ic->timestampPackets, requestAlloc); } else { context->ic->timestampPackets = *enable; } Admin_sendMessage(response, txid, context->admin); }
static void mkNextRequest(struct ReachabilityCollector_pvt* rcp) { struct PeerInfo* pi = NULL; for (int i = 0; i < rcp->piList->length; i++) { pi = ArrayList_OfPeerInfo_get(rcp->piList, i); if (!pi->querying) { continue; } } if (!pi || !pi->querying) { return; } rcp->msgOnWire = MsgCore_createQuery(rcp->msgCore, TIMEOUT_MILLISECONDS, rcp->alloc); rcp->msgOnWire->userData = rcp; rcp->msgOnWire->cb = onReply; rcp->msgOnWire->target = Address_clone(&pi->addr, rcp->msgOnWire->alloc); Dict* d = rcp->msgOnWire->msg = Dict_new(rcp->msgOnWire->alloc); Dict_putStringCC(d, "q", "gp", rcp->msgOnWire->alloc); uint64_t label_be = Endian_hostToBigEndian64(pi->pathToCheck); Dict_putStringC(d, "tar", String_newBinary((uint8_t*) &label_be, 8, rcp->msgOnWire->alloc), rcp->msgOnWire->alloc); BoilerplateResponder_addBoilerplate(rcp->br, d, &pi->addr, rcp->msgOnWire->alloc); }
static void mkNextRequest(struct ReachabilityCollector_pvt* rcp) { struct PeerInfo_pvt* pi = NULL; for (int i = 0; i < rcp->piList->length; i++) { pi = ArrayList_OfPeerInfo_pvt_get(rcp->piList, i); if (pi->pub.querying && !pi->waitForResponse) { break; } } if (!pi || !pi->pub.querying) { Log_debug(rcp->log, "All [%u] peers have been queried", rcp->piList->length); return; } if (pi->waitForResponse) { Log_debug(rcp->log, "Peer is waiting for response."); return; } struct MsgCore_Promise* query = MsgCore_createQuery(rcp->msgCore, TIMEOUT_MILLISECONDS, rcp->alloc); struct Query* q = Allocator_calloc(query->alloc, sizeof(struct Query), 1); q->rcp = rcp; q->addr = Address_toString(&pi->pub.addr, query->alloc); query->userData = q; query->cb = onReply; Assert_true(AddressCalc_validAddress(pi->pub.addr.ip6.bytes)); query->target = Address_clone(&pi->pub.addr, query->alloc); Dict* d = query->msg = Dict_new(query->alloc); Dict_putStringCC(d, "q", "gp", query->alloc); uint64_t label_be = Endian_hostToBigEndian64(pi->pathToCheck); uint8_t nearbyLabelBytes[8]; Bits_memcpy(nearbyLabelBytes, &label_be, 8); AddrTools_printPath(q->targetPath, pi->pathToCheck); Log_debug(rcp->log, "Getting peers for peer [%s] tar [%s]", q->addr->bytes, q->targetPath); Dict_putStringC(d, "tar", String_newBinary(nearbyLabelBytes, 8, query->alloc), query->alloc); BoilerplateResponder_addBoilerplate(rcp->br, d, &pi->pub.addr, query->alloc); pi->waitForResponse = true; }
static void pingCycle(void* vsn) { struct SupernodeHunter_pvt* snp = Identity_check((struct SupernodeHunter_pvt*) vsn); if (snp->pub.snodeIsReachable) { return; } if (!snp->authorizedSnodes->length) { return; } if (!snp->peers->length) { return; } Log_debug(snp->log, "\n\nping cycle\n\n"); // We're not handling replies... struct MsgCore_Promise* qp = MsgCore_createQuery(snp->msgCore, 0, snp->alloc); struct Query* q = Allocator_calloc(qp->alloc, sizeof(struct Query), 1); Identity_set(q); q->snp = snp; q->sendTime = Time_currentTimeMilliseconds(snp->base); Dict* msg = qp->msg = Dict_new(qp->alloc); qp->cb = onReply; qp->userData = q; bool isGetPeers = snp->nodeListIndex & 1; int idx = snp->nodeListIndex++ >> 1; for (;;) { if (idx < snp->peers->length) { qp->target = AddrSet_get(snp->peers, idx); break; } idx -= snp->peers->length; if (idx < snp->nodes->length) { qp->target = AddrSet_get(snp->nodes, idx); break; } snp->snodeAddrIdx++; idx -= snp->nodes->length; } struct Address* snode = AddrSet_get(snp->authorizedSnodes, snp->snodeAddrIdx % snp->authorizedSnodes->length); if (Address_isSameIp(snode, qp->target)) { // Supernode is a peer... AddrSet_add(snp->snodeCandidates, qp->target); } if (snp->snodeCandidates->length) { qp->target = AddrSet_get(snp->snodeCandidates, snp->snodeCandidates->length - 1); Log_debug(snp->log, "Sending getRoute to snode %s", Address_toString(qp->target, qp->alloc)->bytes); Dict_putStringCC(msg, "sq", "gr", qp->alloc); Dict_putStringC(msg, "src", snp->selfAddrStr, qp->alloc); String* target = String_newBinary(qp->target->ip6.bytes, 16, qp->alloc); Dict_putStringC(msg, "tar", target, qp->alloc); q->isGetRoute = true; return; } if (isGetPeers) { Log_debug(snp->log, "Sending getPeers to %s", Address_toString(qp->target, qp->alloc)->bytes); Dict_putStringCC(msg, "q", "gp", qp->alloc); Dict_putStringC(msg, "tar", String_newBinary("\0\0\0\0\0\0\0\1", 8, qp->alloc), qp->alloc); } else { q->searchTar = Address_clone(snode, qp->alloc); Log_debug(snp->log, "Sending findNode to %s", Address_toString(qp->target, qp->alloc)->bytes); Dict_putStringCC(msg, "q", "fn", qp->alloc); Dict_putStringC(msg, "tar", String_newBinary(snode->ip6.bytes, 16, qp->alloc), qp->alloc); } }