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 sendFirstMessageToCore(void* vcontext) { struct NodeContext* ctx = Identity_check((struct NodeContext*) vcontext); struct Allocator* alloc = Allocator_child(ctx->alloc); struct Message* msg = Message_new(0, 512, alloc); Dict* d = Dict_new(alloc); Dict_putString(d, String_CONST("privateKey"), String_new(ctx->privateKeyHex, alloc), alloc); Dict* logging = Dict_new(alloc); { Dict_putString(logging, String_CONST("logTo"), String_CONST("stdout"), alloc); } Dict_putDict(d, String_CONST("logging"), logging, alloc); Dict* admin = Dict_new(alloc); { Dict_putString(admin, String_CONST("bind"), ctx->bind, alloc); Dict_putString(admin, String_CONST("pass"), ctx->pass, alloc); } Dict_putDict(d, String_CONST("admin"), admin, alloc); BencMessageWriter_write(d, msg, NULL); Iface_send(&ctx->angelIface, msg); Allocator_free(alloc); }
static void handleRequestFromChild(struct Admin* admin, uint8_t buffer[MAX_API_REQUEST_SIZE], size_t amount, struct Allocator* allocator) { String* txid = NULL; int skip = 0; if (!memcmp(buffer, "0123", 4)) { // out of band txid txid = &(String) { .len = 4, .bytes = (char*) buffer + 4 }; skip = 8; } struct Reader* reader = ArrayReader_new(buffer + skip, amount - skip, allocator); Dict message; if (List_getStandardBencSerializer()->parseDictionary(reader, allocator, &message)) { return; } String* query = Dict_getString(&message, CJDHTConstants_QUERY); if (!query) { return; } // If they're asking for a cookie then lets give them one. String* cookie = BSTR("cookie"); if (String_equals(query, cookie)) { Dict* d = Dict_new(allocator); char bytes[32]; snprintf(bytes, 32, "%u", (uint32_t) Time_currentTimeSeconds(admin->eventBase)); String* theCookie = &(String) { .len = strlen(bytes), .bytes = bytes }; Dict_putString(d, cookie, theCookie, allocator); Admin_sendMessage(d, txid, admin); return; } // If this is a permitted query, make sure the cookie is right. String* auth = BSTR("auth"); bool authed = false; if (String_equals(query, auth)) { if (!authValid(&message, buffer + skip, reader->bytesRead(reader), admin)) { Dict* d = Dict_new(allocator); Dict_putString(d, BSTR("error"), BSTR("Auth failed."), allocator); Admin_sendMessage(d, txid, admin); return; } query = Dict_getString(&message, BSTR("aq")); authed = true; } for (int i = 0; i < admin->functionCount; i++) { if (String_equals(query, admin->functions[i].name) && (authed || !admin->functions[i].needsAuth)) { admin->functions[i].call(&message, admin->functions[i].context, txid); } } return; }
static void dns(Dict* dns, struct Context* ctx, struct Except* eh) { List* servers = Dict_getList(dns, String_CONST("servers")); int count = List_size(servers); for (int i = 0; i < count; i++) { String* server = List_getString(servers, i); if (!server) { Except_throw(eh, "dns.servers[%d] is not a string", i); } Dict* d = Dict_new(ctx->alloc); Dict_putString(d, String_CONST("addr"), server, ctx->alloc); rpcCall(String_CONST("RainflyClient_addServer"), d, ctx, ctx->alloc); } List* keys = Dict_getList(dns, String_CONST("keys")); count = List_size(keys); for (int i = 0; i < count; i++) { String* key = List_getString(keys, i); if (!key) { Except_throw(eh, "dns.keys[%d] is not a string", i); } Dict* d = Dict_new(ctx->alloc); Dict_putString(d, String_CONST("ident"), key, ctx->alloc); rpcCall(String_CONST("RainflyClient_addKey"), d, ctx, ctx->alloc); } int64_t* minSigs = Dict_getInt(dns, String_CONST("minSignatures")); if (minSigs) { Dict* d = Dict_new(ctx->alloc); Dict_putInt(d, String_CONST("count"), *minSigs, ctx->alloc); rpcCall(String_CONST("RainflyClient_minSignatures"), d, ctx, ctx->alloc); } }
static String* getExpectedResponse(struct Sockaddr* sa4, int prefix4, int alloc4, struct Sockaddr* sa6, int prefix6, int alloc6, struct Allocator* allocator) { Assert_true(alloc6 >= prefix6); Assert_true(alloc4 >= prefix4); struct Allocator* alloc = Allocator_child(allocator); Dict* addresses = Dict_new(alloc); if (sa4) { uint8_t* addr = NULL; Assert_true(Sockaddr_getAddress(sa4, &addr) == 4); String* addrStr = String_newBinary(addr, 4, alloc); Dict_putString(addresses, String_new("ip4", alloc), addrStr, alloc); Dict_putInt(addresses, String_new("ip4Prefix", alloc), prefix4, alloc); Dict_putInt(addresses, String_new("ip4Alloc", alloc), alloc4, alloc); } if (sa6) { uint8_t* addr = NULL; Assert_true(Sockaddr_getAddress(sa6, &addr) == 16); String* addrStr = String_newBinary(addr, 16, alloc); Dict_putString(addresses, String_new("ip6", alloc), addrStr, alloc); Dict_putInt(addresses, String_new("ip6Prefix", alloc), prefix6, alloc); Dict_putInt(addresses, String_new("ip6Alloc", alloc), alloc6, alloc); } Dict* output = Dict_new(alloc); Dict_putDict(output, String_new("addresses", alloc), addresses, alloc); Dict_putString(output, String_new("txid", alloc), String_new("abcd", alloc), alloc); struct Message* msg = Message_new(0, 512, alloc); BencMessageWriter_write(output, msg, NULL); String* outStr = String_newBinary(msg->bytes, msg->length, allocator); Allocator_free(alloc); return outStr; }
static void tunInterface(Dict* ifaceConf, struct Allocator* tempAlloc, struct Context* ctx) { String* ifaceType = Dict_getString(ifaceConf, String_CONST("type")); if (!String_equals(ifaceType, String_CONST("TUNInterface"))) { return; } // Setup the interface. String* tunfd = Dict_getString(ifaceConf, String_CONST("tunfd")); String* device = Dict_getString(ifaceConf, String_CONST("tunDevice")); Dict* args = Dict_new(tempAlloc); if (tunfd && device) { Dict_putString(args, String_CONST("path"), device, tempAlloc); Dict_putString(args, String_CONST("type"), String_new(tunfd->bytes, tempAlloc), tempAlloc); Dict* res = NULL; rpcCall0(String_CONST("FileNo_import"), args, ctx, tempAlloc, &res, false); if (res) { Dict* args = Dict_new(tempAlloc); int64_t* tunfd = Dict_getInt(res, String_CONST("tunfd")); int64_t* type = Dict_getInt(res, String_CONST("type")); Dict_putInt(args, String_CONST("tunfd"), *tunfd, tempAlloc); Dict_putInt(args, String_CONST("type"), *type, tempAlloc); rpcCall0(String_CONST("Core_initTunfd"), args, ctx, tempAlloc, NULL, false); } } else { if (device) { Dict_putString(args, String_CONST("desiredTunName"), device, tempAlloc); } rpcCall0(String_CONST("Core_initTunnel"), args, ctx, tempAlloc, NULL, false); } }
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 dumpTable(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* ctx = Identity_check((struct Context*) vcontext); int64_t* page = Dict_getInt(args, String_CONST("page")); int ctr = (page) ? *page * ENTRIES_PER_PAGE : 0; Dict* out = Dict_new(requestAlloc); List* table = List_new(requestAlloc); struct Node_Two* nn = NULL; for (int i = 0; i < ctr+ENTRIES_PER_PAGE; i++) { nn = NodeStore_getNextNode(ctx->store, nn); if (!nn) { break; } if (i < ctr) { continue; } Dict* nodeDict = Dict_new(requestAlloc); String* ip = String_newBinary(NULL, 39, requestAlloc); Address_printIp(ip->bytes, &nn->address); Dict_putString(nodeDict, String_CONST("ip"), ip, requestAlloc); String* addr = Address_toString(&nn->address, requestAlloc); Dict_putString(nodeDict, String_CONST("addr"), addr, requestAlloc); String* path = String_newBinary(NULL, 19, requestAlloc); AddrTools_printPath(path->bytes, nn->address.path); Dict_putString(nodeDict, String_CONST("path"), path, requestAlloc); Dict_putInt(nodeDict, String_CONST("link"), Node_getCost(nn), requestAlloc); Dict_putInt(nodeDict, String_CONST("version"), nn->address.protocolVersion, requestAlloc); Dict_putInt(nodeDict, String_CONST("time"), NodeStore_timeSinceLastPing(ctx->store, nn), requestAlloc); Dict_putInt(nodeDict, String_CONST("bucket"), NodeStore_bucketForAddr(ctx->store->selfAddress, &nn->address), requestAlloc); List_addDict(table, nodeDict, requestAlloc); } Dict_putList(out, String_CONST("routingTable"), table, requestAlloc); if (nn) { Dict_putInt(out, String_CONST("more"), 1, requestAlloc); } Dict_putInt(out, String_CONST("count"), ctx->store->nodeCount, requestAlloc); Dict_putInt(out, String_CONST("peers"), ctx->store->peerCount, requestAlloc); Dict_putString(out, String_CONST("deprecation"), String_CONST("ip,path,version will soon be removed"), requestAlloc); Admin_sendMessage(out, txid, ctx->admin); }
int main(int argc, char** argv) { struct AdminTestFramework* fw = AdminTestFramework_setUp(argc, argv, "UDPInterface_test"); // mock interface controller. struct InterfaceController ifController = { .registerPeer = registerPeer }; UDPInterface_admin_register(fw->eventBase, fw->alloc, fw->logger, fw->admin, &ifController); Dict* dict = Dict_new(fw->alloc); struct AdminClient_Promise* promise = AdminClient_rpcCall(String_CONST("UDPInterface_new"), dict, fw->client, fw->alloc); promise->callback = ifNewCallback; promise->userData = fw; EventBase_beginLoop(fw->eventBase); // bad key dict = Dict_new(fw->alloc); Dict_putString(dict, String_CONST("publicKey"), String_CONST("notAValidKey"), fw->alloc); Dict_putString(dict, String_CONST("address"), String_CONST("127.0.0.1:12345"), fw->alloc); promise = AdminClient_rpcCall( String_CONST("UDPInterface_beginConnection"), dict, fw->client, fw->alloc); promise->callback = badKeyCallback; promise->userData = fw; EventBase_beginLoop(fw->eventBase); dict = Dict_new(fw->alloc); Dict_putString(dict, String_CONST("publicKey"), String_CONST("c86pf0ngj3wlb569juqm10yzv29n9t4w5tmsyhx6xd3fbqjlcu50.k"), fw->alloc); Dict_putString(dict, String_CONST("address"), String_CONST("127.0.0.1:12345"), fw->alloc); promise = AdminClient_rpcCall( String_CONST("UDPInterface_beginConnection"), dict, fw->client, fw->alloc); promise->callback = goodCallback; promise->userData = fw; EventBase_beginLoop(fw->eventBase); AdminTestFramework_tearDown(fw); return 0; }
void Admin_registerFunctionWithArgCount(char* name, Admin_FUNCTION(callback), void* callbackContext, bool needsAuth, struct Admin_FunctionArg* arguments, int argCount, struct Admin* admin) { if (!admin) { return; } String* str = String_new(name, admin->allocator); if (!admin->functionCount) { admin->functions = admin->allocator->malloc(sizeof(struct Function), admin->allocator); } else { admin->functions = admin->allocator->realloc(admin->functions, sizeof(struct Function) * (admin->functionCount + 1), admin->allocator); } struct Function* fu = &admin->functions[admin->functionCount]; admin->functionCount++; fu->name = str; fu->call = callback; fu->context = callbackContext; fu->needsAuth = needsAuth; fu->args = Dict_new(admin->allocator); for (int i = 0; arguments && i < argCount; i++) { // "type" must be one of: [ "String", "Int", "Dict", "List" ] String* type = NULL; if (!strcmp(arguments[i].type, STRING->bytes)) { type = STRING; } else if (!strcmp(arguments[i].type, INT->bytes)) { type = INT; } else if (!strcmp(arguments[i].type, DICT->bytes)) { type = DICT; } else if (!strcmp(arguments[i].type, LIST->bytes)) { type = LIST; } else { abort(); } Dict* arg = Dict_new(admin->allocator); Dict_putString(arg, TYPE, type, admin->allocator); Dict_putInt(arg, REQUIRED, arguments[i].required, admin->allocator); String* name = String_new(arguments[i].name, admin->allocator); Dict_putDict(fu->args, name, arg, admin->allocator); } }
static void adminPeerStats(Dict* args, void* vcontext, String* txid, struct Allocator* alloc) { struct Context* context = Identity_check((struct Context*)vcontext); struct InterfaceController_PeerStats* stats = NULL; int64_t* page = Dict_getIntC(args, "page"); int i = (page) ? *page * ENTRIES_PER_PAGE : 0; int count = InterfaceController_getPeerStats(context->ic, alloc, &stats); List* list = List_new(alloc); for (int counter=0; i < count && counter++ < ENTRIES_PER_PAGE; i++) { Dict* d = Dict_new(alloc); Dict_putIntC(d, "bytesIn", stats[i].bytesIn, alloc); Dict_putIntC(d, "bytesOut", stats[i].bytesOut, alloc); Dict_putIntC(d, "recvKbps", stats[i].recvKbps, alloc); Dict_putIntC(d, "sendKbps", stats[i].sendKbps, alloc); Dict_putStringC(d, "addr", Address_toString(&stats[i].addr, alloc), alloc); String* stateString = String_new(InterfaceController_stateString(stats[i].state), alloc); Dict_putStringC(d, "state", stateString, alloc); Dict_putIntC(d, "last", stats[i].timeOfLastMessage, alloc); Dict_putIntC(d, "isIncoming", stats[i].isIncomingConnection, alloc); Dict_putIntC(d, "duplicates", stats[i].duplicates, alloc); Dict_putIntC(d, "lostPackets", stats[i].lostPackets, alloc); Dict_putIntC(d, "receivedOutOfRange", stats[i].receivedOutOfRange, alloc); if (stats[i].user) { Dict_putStringC(d, "user", stats[i].user, alloc); } List_addDict(list, d, alloc); } Dict* resp = Dict_new(alloc); Dict_putListC(resp, "peers", 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 checkRunningInstance(struct Allocator* allocator, struct EventBase* base, String* addr, String* password, struct Log* logger, struct Except* eh) { struct Allocator* alloc = Allocator_child(allocator); struct Sockaddr_storage pingAddrStorage; if (Sockaddr_parse(addr->bytes, &pingAddrStorage)) { Except_raise(eh, -1, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234", addr->bytes); } struct AdminClient* adminClient = AdminClient_new(&pingAddrStorage.addr, password, base, logger, alloc); // 100 milliseconds is plenty to wait for a process to respond on the same machine. adminClient->millisecondsToWait = 100; Dict* pingArgs = Dict_new(alloc); struct AdminClient_Result* pingResult = AdminClient_rpcCall(String_new("ping", alloc), pingArgs, adminClient, alloc); if (pingResult->err == AdminClient_Error_NONE) { Except_raise(eh, -1, "Startup failed: cjdroute is already running."); } Allocator_free(alloc); }
static void bytesAllocated(Dict* in, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Allocator_admin_pvt* ctx = Identity_check((struct Allocator_admin_pvt*)vcontext); Dict* d = Dict_new(requestAlloc); Dict_putIntC(d, "bytes", Allocator_bytesAllocated(ctx->alloc), requestAlloc); Admin_sendMessage(d, txid, ctx->admin); }
static Dict* makeLogMessage(struct Subscription* subscription, struct AdminLog* logger, enum Log_Level logLevel, const char* fullFilePath, uint32_t line, const char* format, va_list vaArgs, struct Allocator* alloc) { time_t now; time(&now); Dict* out = Dict_new(alloc); char* buff = Allocator_malloc(alloc, 20); Hex_encode((uint8_t*)buff, 20, subscription->streamId, 8); Dict_putString(out, String_new("streamId", alloc), String_new(buff, alloc), alloc); Dict_putInt(out, String_new("time", alloc), now, alloc); Dict_putString(out, String_new("level", alloc), String_new(Log_nameForLevel(logLevel), alloc), alloc); const char* shortName = getShortName(fullFilePath); Dict_putString(out, String_new("file", alloc), String_new((char*)shortName, alloc), alloc); Dict_putInt(out, String_new("line", alloc), line, alloc); String* message = String_vprintf(alloc, format, vaArgs); // Strip all of the annoying \n marks in the log entries. if (message->len > 0 && message->bytes[message->len - 1] == '\n') { message->len--; } Dict_putString(out, String_new("message", alloc), message, alloc); return out; }
static void showActiveSearch(Dict* args, void* vctx, String* txid, struct Allocator* alloc) { struct Context* ctx = Identity_check((struct Context*) vctx); int number = *(Dict_getIntC(args, "number")); struct SearchRunner_SearchData* search = SearchRunner_showActiveSearch(ctx->runner, number, alloc); Dict* dict = Dict_new(alloc); // Nothing is an error Dict_putString(dict, String_new("error", alloc), String_new("none", alloc), alloc); if (number < search->activeSearches) { uint8_t target[40]; AddrTools_printIp(target, search->target); Dict_putString(dict, String_new("target", alloc), String_new((char*)target, alloc), alloc); uint8_t lastNodeAsked[60]; Address_print(lastNodeAsked, &search->lastNodeAsked); Dict_putString(dict, String_new("lastNodeAsked", alloc), String_new((char*)lastNodeAsked, alloc), alloc); Dict_putInt(dict, String_new("totalRequests", alloc), search->totalRequests, alloc); } Dict_putInt(dict, String_new("activeSearches", alloc), search->activeSearches, alloc); Admin_sendMessage(dict, txid, ctx->admin); }
static void getHandles(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*) vcontext); struct Allocator* alloc = Allocator_child(context->alloc); int64_t* page = Dict_getInt(args, String_CONST("page")); int i = (page) ? *page * ENTRIES_PER_PAGE : 0; struct SessionManager_HandleList* hList = SessionManager_getHandleList(context->sm, alloc); List* list = List_new(alloc); for (int counter = 0; i < hList->length && counter++ < ENTRIES_PER_PAGE; i++) { List_addInt(list, hList->handles[i], alloc); } Dict* r = Dict_new(alloc); Dict_putList(r, String_CONST("handles"), list, alloc); Dict_putInt(r, String_CONST("total"), hList->length, alloc); String* more = String_CONST("more"); if (i < hList->length) { Dict_putInt(r, more, 1, alloc); } Admin_sendMessage(r, txid, context->admin); Allocator_free(alloc); }
static void addServer(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = vcontext; struct Allocator* alloc = Allocator_child(context->alloc); String* addrStr = Dict_getString(args, String_CONST("addr")); int ret; struct Sockaddr_storage ss; char* err = "none"; if (Sockaddr_parse(addrStr->bytes, &ss)) { err = "could not parse address"; } else if ((ret = RainflyClient_addServer(context->rainfly, &ss.addr))) { if (ret == RainflyClient_addServer_WRONG_ADDRESS_TYPE) { err = "RainflyClient_addServer_WRONG_ADDRESS_TYPE"; } else { err = "unknown error"; } } Dict* response = Dict_new(alloc); Dict_putString(response, String_CONST("error"), String_CONST(err), alloc); Admin_sendMessage(response, txid, context->admin); Allocator_free(alloc); }
static void adminPingOnResponse(struct SwitchPinger_Response* resp, void* vping) { struct Allocator* pingAlloc = resp->ping->pingAlloc; struct Ping* ping = vping; Dict* rd = Dict_new(pingAlloc); if (resp->res == SwitchPinger_Result_LABEL_MISMATCH) { uint8_t path[20] = {0}; AddrTools_printPath(path, resp->label); String* pathStr = String_new(path, pingAlloc); Dict_putString(rd, String_CONST("rpath"), pathStr, pingAlloc); } Dict_putInt(rd, String_CONST("version"), resp->version, pingAlloc); Dict_putInt(rd, String_CONST("ms"), resp->milliseconds, pingAlloc); Dict_putString(rd, String_CONST("result"), SwitchPinger_resultString(resp->res), pingAlloc); Dict_putString(rd, String_CONST("path"), ping->path, pingAlloc); if (resp->data) { Dict_putString(rd, String_CONST("data"), resp->data, pingAlloc); } if (!Bits_isZero(resp->key, 32)) { Dict_putString(rd, String_CONST("key"), Key_stringify(resp->key, pingAlloc), pingAlloc); } Admin_sendMessage(rd, ping->txid, ping->context->admin); }
static void dumpRumorMill(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* ctx = Identity_check((struct Context*) vcontext); Dict* out = Dict_new(requestAlloc); struct RumorMill* rm = getRumorMill(ctx, Dict_getString(args, String_CONST("mill"))); if (!rm) { Dict_putString(out, String_CONST("error"), String_CONST("mill must be one of " "[externalMill,linkMill,nodeMill,dhtMill,splitMill]"), requestAlloc); Admin_sendMessage(out, txid, ctx->admin); return; } int64_t* page = Dict_getInt(args, String_CONST("page")); int ctr = (page) ? *page * ENTRIES_PER_PAGE : 0; List* table = List_new(requestAlloc); for (int i = 0; i < ENTRIES_PER_PAGE && ctr < rm->count; i++) { String* addr = Address_toString(&rm->addresses[ctr++], requestAlloc); List_addString(table, addr, requestAlloc); } Dict_putList(out, String_CONST("addresses"), table, requestAlloc); Dict_putInt(out, String_CONST("total"), rm->count, requestAlloc); Admin_sendMessage(out, txid, ctx->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 adminDisconnectPeer(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*)vcontext); String* pubkeyString = Dict_getString(args, String_CONST("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_putInt(response, String_CONST("success"), error ? 0 : 1, requestAlloc); if (error) { Dict_putString(response, String_CONST("error"), String_CONST(errorMsg), requestAlloc); } Admin_sendMessage(response, txid, context->admin); }
static void addKey(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = vcontext; struct Allocator* alloc = Allocator_child(context->alloc); String* identStr = Dict_getString(args, String_CONST("ident")); int ret; uint8_t key[32]; char* err = "none"; if (identStr->len < 52) { err = "too short"; } else if (Base32_decode(key, 32, identStr->bytes, 52) != 32) { err = "failed to parse"; } else if ((ret = RainflyClient_addKey(context->rainfly, key))) { if (ret == RainflyClient_addKey_TOO_MANY_KEYS) { err = "RainflyClient_addKey_TOO_MANY_KEYS"; } else { err = "unknown error"; } } Dict* response = Dict_new(alloc); Dict_putString(response, String_CONST("error"), String_CONST(err), alloc); Admin_sendMessage(response, txid, context->admin); Allocator_free(alloc); }
static void getSomething(Dict* args, struct RouteGen_admin_Ctx* ctx, String* txid, struct Allocator* requestAlloc, Dict* genRoutes) { int page = getIntVal(args, String_CONST("page")); List* routes; if (getIntVal(args, String_CONST("ip6"))) { routes = Dict_getList(genRoutes, String_CONST("ipv6")); } else { routes = Dict_getList(genRoutes, String_CONST("ipv4")); } Assert_true(routes); List* outList = List_new(requestAlloc); bool more = false; for (int i = page * ROUTES_PER_PAGE, j = 0; i < List_size(routes) && j < ROUTES_PER_PAGE; j++) { String* route = List_getString(routes, i); Assert_true(route); List_addString(outList, route, requestAlloc); if (++i >= List_size(routes)) { more = false; break; } more = true; } Dict* out = Dict_new(requestAlloc); if (more) { Dict_putInt(out, String_new("more", requestAlloc), 1, requestAlloc); } Dict_putList(out, String_new("routes", requestAlloc), outList, requestAlloc); Admin_sendMessage(out, txid, ctx->admin); }
static void newInterface2(struct Context* ctx, struct Sockaddr* addr, String* txid, struct Allocator* requestAlloc) { struct Allocator* const alloc = Allocator_child(ctx->alloc); struct UDPAddrIface* udpIf = NULL; struct Jmp jmp; Jmp_try(jmp) { udpIf = UDPAddrIface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger); } Jmp_catch { String* errStr = String_CONST(jmp.message); Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL); Admin_sendMessage(&out, txid, ctx->admin); Allocator_free(alloc); return; } struct AddrIface* ai = ctx->udpIf = &udpIf->generic; struct InterfaceController_Iface* ici = InterfaceController_newIface(ctx->ic, String_CONST("UDP"), alloc); Iface_plumb(&ici->addrIf, &ai->iface); Dict* out = Dict_new(requestAlloc); Dict_putString(out, String_CONST("error"), String_CONST("none"), requestAlloc); Dict_putInt(out, String_CONST("interfaceNumber"), ici->ifNum, requestAlloc); char* printedAddr = Sockaddr_print(ai->addr, requestAlloc); Dict_putString(out, String_CONST("bindAddress"), String_CONST(printedAddr), requestAlloc); Admin_sendMessage(out, txid, ctx->admin); }
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 showConn(struct IpTunnel_Connection* conn, String* txid, struct Admin* admin, struct Allocator* alloc) { Dict* d = Dict_new(alloc); if (!Bits_isZero(conn->connectionIp6, 16)) { struct Sockaddr* addr = Sockaddr_clone(Sockaddr_LOOPBACK6, alloc); uint8_t* address; Assert_true(16 == Sockaddr_getAddress(addr, &address)); Bits_memcpy(address, conn->connectionIp6, 16); char* printedAddr = Sockaddr_print(addr, alloc); Dict_putString(d, String_CONST("ip6Address"), String_CONST(printedAddr), alloc); Dict_putInt(d, String_CONST("ip6Prefix"), conn->connectionIp6Prefix, alloc); } if (!Bits_isZero(conn->connectionIp4, 4)) { struct Sockaddr* addr = Sockaddr_clone(Sockaddr_LOOPBACK, alloc); uint8_t* address; Assert_true(4 == Sockaddr_getAddress(addr, &address)); Bits_memcpy(address, conn->connectionIp4, 4); char* printedAddr = Sockaddr_print(addr, alloc); Dict_putString(d, String_CONST("ip4Address"), String_CONST(printedAddr), alloc); Dict_putInt(d, String_CONST("ip4Prefix"), conn->connectionIp4Prefix, alloc); } Dict_putString(d, String_CONST("key"), Key_stringify(conn->routeHeader.publicKey, alloc), alloc); Dict_putInt(d, String_CONST("outgoing"), (conn->isOutgoing) ? 1 : 0, alloc); Dict_putString(d, String_CONST("error"), String_CONST("none"), alloc); Admin_sendMessage(d, txid, admin); }
static Dict* serialize(void* vcontext) { char* buffer = calloc(2048, 1); struct Allocator* allocator = BufferAllocator_new(buffer, 2048); Dict* out = Dict_new(allocator); Dict_putString(out, &hi, String_new((char*) vcontext, allocator), allocator); return out; }
Dict* Security_getUser(char* userName, struct Allocator* retAlloc) { Dict* ret = Dict_new(retAlloc); Dict_putString(ret, String_new("error", retAlloc), String_new("Not supported on windows", retAlloc), retAlloc); return ret; }
static void sendResponse(String* error, struct Admin* admin, String* txid, struct Allocator* tempAlloc) { Dict* output = Dict_new(tempAlloc); Dict_putString(output, String_CONST("error"), error, tempAlloc); Admin_sendMessage(output, txid, admin); }