Example #1
0
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;
    }
}
Example #2
0
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);
}
Example #3
0
static void newInterface2(struct Context* ctx,
                          struct Sockaddr* addr,
                          String* txid)
{
    struct Allocator* const alloc = Allocator_child(ctx->allocator);
    struct UDPInterface* udpIf = NULL;
    struct Jmp jmp;
    Jmp_try(jmp) {
        udpIf = UDPInterface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger, ctx->ic);
    } 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);
    }

    // sizeof(struct UDPInterface*) the size of a pointer.
    ctx->ifaces = Allocator_realloc(ctx->allocator,
                                    ctx->ifaces,
                                    sizeof(struct UDPInterface*) * (ctx->ifCount + 1));
    ctx->ifaces[ctx->ifCount] = udpIf;

    Dict out = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
        String_CONST("interfaceNumber"), Int_OBJ(ctx->ifCount), NULL
    ));

    Admin_sendMessage(&out, txid, ctx->admin);
    ctx->ifCount++;
}
Example #4
0
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);
}
Example #5
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);
}
Example #6
0
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;
}
Example #7
0
static void subscribe(Dict* args, void* vcontext, String* txid)
{
    struct AdminLog* log = (struct AdminLog*) vcontext;
    String* levelName = Dict_getString(args, String_CONST("level"));
    enum Log_Level level = (levelName) ? Log_levelForName(levelName->bytes) : Log_Level_DEBUG;
    int64_t* lineNumPtr = Dict_getInt(args, String_CONST("line"));
    String* fileStr = Dict_getString(args, String_CONST("file"));
    const char* file = (fileStr && fileStr->len > 0) ? fileStr->bytes : NULL;
    char* error = "2+2=5";
    if (level == Log_Level_INVALID) {
        level = Log_Level_KEYS;
    }
    if (lineNumPtr && *lineNumPtr < 0) {
        error = "Invalid line number, must be positive or 0 to signify any line is acceptable.";
    } else if (log->subscriptionCount >= MAX_SUBSCRIPTIONS) {
        error = "Max subscription count reached.";
    } else {
        struct Subscription* sub = &log->subscriptions[log->subscriptionCount];
        sub->level = level;
        sub->alloc = Allocator_child(log->alloc);
        if (file) {
            int i;
            for (i = 0; i < FILE_NAME_COUNT; i++) {
                if (log->fileNames[i] && !strcmp(log->fileNames[i], file)) {
                    file = log->fileNames[i];
                    sub->internalName = true;
                    break;
                }
            }
            if (i == FILE_NAME_COUNT) {
                file = String_new(file, sub->alloc)->bytes;
                sub->internalName = false;
            }
        }
        sub->file = file;
        sub->lineNum = (lineNumPtr) ? *lineNumPtr : 0;
        sub->txid = String_clone(txid, sub->alloc);
        Random_bytes(log->rand, (uint8_t*) sub->streamId, 8);
        uint8_t streamIdHex[20];
        Hex_encode(streamIdHex, 20, sub->streamId, 8);
        Dict response = Dict_CONST(
            String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
            String_CONST("streamId"), String_OBJ(String_CONST((char*)streamIdHex)), NULL
        ));
        Admin_sendMessage(&response, txid, log->admin);
        log->subscriptionCount++;
        return;
    }

    Dict response = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST(error)), NULL
    );
    Admin_sendMessage(&response, txid, log->admin);
}
Example #8
0
static void sessionStats(Dict* args,
                         void* vcontext,
                         String* txid,
                         struct Allocator* alloc)
{
    struct Context* context = Identity_check((struct Context*) vcontext);
    int64_t* handleP = Dict_getInt(args, String_CONST("handle"));
    uint32_t handle = *handleP;

    struct SessionManager_Session* session = SessionManager_sessionForHandle(handle, context->sm);

    Dict* r = Dict_new(alloc);
    if (!session) {
        Dict_putString(r, String_CONST("error"), String_CONST("no such session"), alloc);
        Admin_sendMessage(r, txid, context->admin);
        return;
    }

    uint8_t printedAddr[40];
    AddrTools_printIp(printedAddr, session->caSession->herIp6);
    Dict_putString(r, String_CONST("ip6"), String_new(printedAddr, alloc), alloc);

    String* state =
        String_new(CryptoAuth_stateString(CryptoAuth_getState(session->caSession)), alloc);
    Dict_putString(r, String_CONST("state"), state, alloc);

    struct ReplayProtector* rp = &session->caSession->replayProtector;
    Dict_putInt(r, String_CONST("duplicates"), rp->duplicates, alloc);
    Dict_putInt(r, String_CONST("lostPackets"), rp->lostPackets, alloc);
    Dict_putInt(r, String_CONST("receivedOutOfRange"), rp->receivedOutOfRange, alloc);

    struct Address addr;
    Bits_memcpyConst(addr.key, session->caSession->herPublicKey, 32);
    addr.path = session->sendSwitchLabel;
    addr.protocolVersion = session->version;

    Dict_putString(r, String_CONST("addr"), Address_toString(&addr, alloc), alloc);

    Dict_putString(r, String_CONST("publicKey"),
                      Key_stringify(session->caSession->herPublicKey, alloc), alloc);
    Dict_putInt(r, String_CONST("version"), session->version, alloc);
    Dict_putInt(r, String_CONST("handle"), session->receiveHandle, alloc);
    Dict_putInt(r, String_CONST("sendHandle"), session->sendHandle, alloc);

    Dict_putInt(r, String_CONST("timeOfLastIn"), session->timeOfLastIn, alloc);
    Dict_putInt(r, String_CONST("timeOfLastOut"), session->timeOfLastOut, alloc);

    Dict_putString(r, String_CONST("deprecation"),
        String_CONST("publicKey,version will soon be removed"), alloc);

    Admin_sendMessage(r, txid, context->admin);
    return;
}
Example #9
0
static void sessionStats(Dict* args,
                         void* vcontext,
                         String* txid,
                         struct Allocator* alloc)
{
    struct Context* context = vcontext;
    int64_t* handleP = Dict_getInt(args, String_CONST("handle"));
    uint32_t handle = *handleP;

    struct SessionManager_Session* session = SessionManager_sessionForHandle(handle, context->sm);
    uint8_t* ip6 = SessionManager_getIp6(handle, context->sm);

    Dict* r = Dict_new(alloc);
    if (!session) {
        Dict_putString(r, String_CONST("error"), String_CONST("no such session"), alloc);
        Admin_sendMessage(r, txid, context->admin);
        return;
    }
    // both or neither
    Assert_true(ip6);

    uint8_t printedAddr[40];
    AddrTools_printIp(printedAddr, ip6);
    Dict_putString(r, String_CONST("ip6"), String_new(printedAddr, alloc), alloc);

    Dict_putString(r,
                   String_CONST("state"),
                   String_new(CryptoAuth_stateString(session->cryptoAuthState), alloc),
                   alloc);

    struct ReplayProtector* rp = CryptoAuth_getReplayProtector(session->internal);
    Dict_putInt(r, String_CONST("duplicates"), rp->duplicates, alloc);
    Dict_putInt(r, String_CONST("lostPackets"), rp->lostPackets, alloc);
    Dict_putInt(r, String_CONST("receivedOutOfRange"), rp->receivedOutOfRange, alloc);

    uint8_t* key = CryptoAuth_getHerPublicKey(session->internal);
    Dict_putString(r, String_CONST("publicKey"), Key_stringify(key, alloc), alloc);
    Dict_putInt(r, String_CONST("version"), session->version, alloc);
    Dict_putInt(r, String_CONST("handle"),
                Endian_bigEndianToHost32(session->receiveHandle_be), alloc);
    Dict_putInt(r, String_CONST("sendHandle"),
                Endian_bigEndianToHost32(session->sendHandle_be), alloc);

    Dict_putInt(r, String_CONST("timeOfLastIn"), session->timeOfLastIn, alloc);
    Dict_putInt(r, String_CONST("timeOfLastOut"), session->timeOfLastOut, alloc);

    Admin_sendMessage(r, txid, context->admin);
    return;
}
Example #10
0
static void adminFunc(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = vcontext;
    ctx->called = true;
    Dict d = Dict_CONST(String_CONST("called!"), Int_OBJ(1), NULL);
    Admin_sendMessage(&d, txid, ctx->framework->admin);
}
Example #11
0
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);
}
Example #12
0
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);
}
Example #13
0
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);
}
Example #14
0
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);
}
Example #15
0
static void getUser(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
{
    struct Context* const ctx = Identity_check((struct Context*) vctx);
    String* user = Dict_getStringC(args, "user");
    Dict* ret = Security_getUser((user) ? user->bytes : NULL, requestAlloc);
    Admin_sendMessage(ret, txid, ctx->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);
}
Example #17
0
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);
}
Example #18
0
static bool checkArgs(Dict* args, struct Function* func, String* txid, struct Admin* admin)
{
    struct Dict_Entry* entry = *func->args;
    String* error = NULL;
    uint8_t buffer[1024];
    struct Allocator* alloc = BufferAllocator_new(buffer, 1024);
    while (entry != NULL) {
        String* key = (String*) entry->key;
        Assert_true(entry->val->type == Object_DICT);
        Dict* value = entry->val->as.dictionary;
        entry = entry->next;
        if (*Dict_getInt(value, String_CONST("required")) == 0) {
            continue;
        }
        String* type = Dict_getString(value, String_CONST("type"));
        if ((type == STRING && !Dict_getString(args, key))
            || (type == DICT && !Dict_getDict(args, key))
            || (type == INTEGER && !Dict_getInt(args, key))
            || (type == LIST && !Dict_getList(args, key)))
        {
            error = String_printf(alloc,
                                  "Entry [%s] is required and must be of type [%s]",
                                  key->bytes,
                                  type->bytes);
            break;
        }
    }
    if (error) {
        Dict d = Dict_CONST(String_CONST("error"), String_OBJ(error), NULL);
        Admin_sendMessage(&d, txid, admin);
    }
    return !error;
}
Example #19
0
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);
}
Example #20
0
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);
}
Example #21
0
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);
}
Example #22
0
static void doLog(struct Log* genericLog,
                  enum Log_Level logLevel,
                  const char* fullFilePath,
                  uint32_t line,
                  const char* format,
                  va_list args)
{
    struct AdminLog* log = (struct AdminLog*) genericLog;
    Dict* message = NULL;
    #define ALLOC_BUFFER_SZ 4096
    uint8_t allocBuffer[ALLOC_BUFFER_SZ];
    for (int i = 0; i < (int)log->subscriptionCount; i++) {
        if (isMatch(&log->subscriptions[i], log, logLevel, fullFilePath, line)) {
            if (!message) {
                struct Allocator* alloc = BufferAllocator_new(allocBuffer, ALLOC_BUFFER_SZ);
                message = makeLogMessage(&log->subscriptions[i],
                                         log,
                                         logLevel,
                                         fullFilePath,
                                         line,
                                         format,
                                         args,
                                         alloc);
            }
            int ret = Admin_sendMessage(message, log->subscriptions[i].txid, log->admin);
            if (ret) {
                removeSubscription(log, &log->subscriptions[i]);
            }
        }
    }
}
Example #23
0
static void lookup(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = vcontext;
    String* addrStr = Dict_getString(args, String_CONST("address"));
    char* err = NULL;
    uint8_t addr[16];
    uint8_t resultBuff[60];
    char* result = (char*) resultBuff;
    if (addrStr->len != 39) {
        err = "address wrong length";
    } else if (AddrTools_parseIp(addr, (uint8_t*) addrStr->bytes)) {
        err = "failed to parse address";
    } else {
        struct Node_Two* n = Router_lookup(ctx->router, addr);
        if (!n) {
            result = "not found";
        } else if (Bits_memcmp(addr, n->address.ip6.bytes, 16)) {
            Address_print(resultBuff, &n->address);
        } else {
            AddrTools_printPath(resultBuff, n->address.path);
        }
    }
    Dict response = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST((err) ? err : "none")), Dict_CONST(
        String_CONST("result"), String_OBJ(String_CONST(result)), NULL
    ));
    Admin_sendMessage(&response, txid, ctx->admin);
}
Example #24
0
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);
}
Example #25
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);
}
Example #26
0
static void sendError(char* error, String* txid, struct Admin* admin)
{
    Dict resp = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST(error)), NULL
    );
    Admin_sendMessage(&resp, txid, admin);
}
Example #27
0
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);
}
Example #28
0
static void adminMemory(Dict* input, void* vcontext, String* txid)
{
    struct MemoryContext* context = vcontext;
    Dict d = Dict_CONST(
        String_CONST("bytes"), Int_OBJ(MallocAllocator_bytesAllocated(context->allocator)), NULL
    );
    Admin_sendMessage(&d, txid, context->admin);
}
Example #29
0
static void sendResponse(int conn, String* txid, struct Admin* admin)
{
    Dict resp = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
        String_CONST("connection"), Int_OBJ(conn), NULL
    ));
    Admin_sendMessage(&resp, txid, admin);
}
Example #30
0
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
    struct Context* context = Identity_check((struct Context*) vcontext);
    Log_info(context->logger, "Got request to exit");
    Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessage(&d, txid, context->admin);
    Timeout_setTimeout(shutdown, context, 1, context->base, context->alloc);
}