Пример #1
0
struct RumorMill* RumorMill_new(struct Allocator* allocator,
                                struct Address* selfAddr,
                                int capacity,
                                struct Log* log,
                                const char* name)
{
    struct Allocator* alloc = Allocator_child(allocator);
    Address_getPrefix(selfAddr);

    struct RumorMill_pvt* rm = Allocator_calloc(alloc, sizeof(struct RumorMill_pvt), 1);
    rm->pub.addresses = Allocator_calloc(alloc, sizeof(struct Address), capacity);
    rm->capacity = capacity;
    rm->selfAddr = Allocator_clone(alloc, selfAddr);
    rm->log = log;
    rm->pub.name = name;
    Identity_set(rm);

    return &rm->pub;
}
Пример #2
0
static struct Address* getNode(String* pathStr,
                               struct Context* ctx,
                               char** errOut,
                               struct Allocator* alloc)
{
    struct Address addr = {.path=0};

    if (pathStr->len == 19 && !AddrTools_parsePath(&addr.path, pathStr->bytes)) {
        struct Node_Link* nl = Router_linkForPath(ctx->router, addr.path);
        if (!nl) {
            *errOut = "not_found";
            return NULL;
        } else {
            Bits_memcpyConst(&addr, &nl->child->address, sizeof(struct Address));
        }
    } else if (pathStr->len == 39 && !AddrTools_parseIp(addr.ip6.bytes, pathStr->bytes)) {
        struct Node_Two* n = Router_lookup(ctx->router, addr.ip6.bytes);
        if (!n || Bits_memcmp(addr.ip6.bytes, n->address.ip6.bytes, 16)) {
            *errOut = "not_found";
            return NULL;
        } else {
            Bits_memcpyConst(&addr, &n->address, sizeof(struct Address));
        }
    } else {
        struct Address* a = Address_fromString(pathStr, alloc);
        if (a) { return a; }
        *errOut = "parse_path";
        return NULL;
    }

    return Allocator_clone(alloc, &addr);
}

static void pingNode(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = Identity_check((struct Context*) vctx);
    String* pathStr = Dict_getString(args, String_CONST("path"));
    int64_t* timeoutPtr = Dict_getInt(args, String_CONST("timeout"));
    uint32_t timeout = (timeoutPtr && *timeoutPtr > 0) ? *timeoutPtr : 0;

    char* err = NULL;
    struct Address* addr = getNode(pathStr, ctx, &err, requestAlloc);

    if (err) {
        Dict errDict = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST(err)), NULL);
        Admin_sendMessage(&errDict, txid, ctx->admin);
        return;
    }

    struct RouterModule_Promise* rp =
        RouterModule_pingNode(addr, timeout, ctx->module, ctx->allocator);
    struct Ping* ping = Allocator_calloc(rp->alloc, sizeof(struct Ping), 1);
    Identity_set(ping);
    ping->txid = String_clone(txid, rp->alloc);
    ping->rp = rp;
    ping->ctx = ctx;
    rp->userData = ping;
    rp->callback = pingResponse;
}

static void getPeers(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = Identity_check((struct Context*) vctx);
    String* nearbyLabelStr = Dict_getString(args, String_CONST("nearbyPath"));
    String* pathStr = Dict_getString(args, String_CONST("path"));
    int64_t* timeoutPtr = Dict_getInt(args, String_CONST("timeout"));
    uint32_t timeout = (timeoutPtr && *timeoutPtr > 0) ? *timeoutPtr : 0;

    char* err = NULL;
    struct Address* addr = getNode(pathStr, ctx, &err, requestAlloc);

    uint64_t nearbyLabel = 0;
    if (!err && nearbyLabelStr) {
        if (nearbyLabelStr->len != 19 || AddrTools_parsePath(&nearbyLabel, nearbyLabelStr->bytes)) {
            err = "parse_nearbyLabel";
        }
    }

    if (err) {
        Dict errDict = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST(err)), NULL);
        Admin_sendMessage(&errDict, txid, ctx->admin);
        return;
    }

    struct RouterModule_Promise* rp =
        RouterModule_getPeers(addr, nearbyLabel, timeout, ctx->module, ctx->allocator);

    struct Ping* ping = Allocator_calloc(rp->alloc, sizeof(struct Ping), 1);
    Identity_set(ping);
    ping->txid = String_clone(txid, rp->alloc);
    ping->rp = rp;
    ping->ctx = ctx;
    rp->userData = ping;
    rp->callback = getPeersResponse;
}

static void findNode(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
{
    struct Context* ctx = Identity_check((struct Context*) vctx);
    String* nodeToQueryStr = Dict_getString(args, String_CONST("nodeToQuery"));
    String* targetStr = Dict_getString(args, String_CONST("target"));
    int64_t* timeoutPtr = Dict_getInt(args, String_CONST("timeout"));
    uint32_t timeout = (timeoutPtr && *timeoutPtr > 0) ? *timeoutPtr : 0;

    char* err = NULL;
    struct Address* nodeToQuery = getNode(nodeToQueryStr, ctx, &err, requestAlloc);
    uint8_t target[16];

    if (!err) {
        if (targetStr->len != 39 || AddrTools_parseIp(target, targetStr->bytes)) {
            err = "parse_target";
        }
    }

    if (err) {
        Dict errDict = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST(err)), NULL);
        Admin_sendMessage(&errDict, txid, ctx->admin);
        return;
    }

    struct RouterModule_Promise* rp =
        RouterModule_findNode(nodeToQuery, target, timeout, ctx->module, ctx->allocator);

    struct Ping* ping = Allocator_calloc(rp->alloc, sizeof(struct Ping), 1);
    Identity_set(ping);
    ping->txid = String_clone(txid, rp->alloc);
    ping->rp = rp;
    ping->ctx = ctx;
    rp->userData = ping;
    rp->callback = findNodeResponse;
}

void RouterModule_admin_register(struct RouterModule* module,
                                 struct Router* router,
                                 struct Admin* admin,
                                 struct Allocator* alloc)
{
    // for improved reporting
    alloc = Allocator_child(alloc);
    struct Context* ctx = Allocator_clone(alloc, (&(struct Context) {
        .admin = admin,
        .allocator = alloc,
        .module = module,
        .router = router
    }));
Пример #3
0
static struct Address* createAddress(int mostSignificantAddressSpaceByte, int* hops)
{
    uint64_t path = getPath(hops);
    struct Address address = { .path = 0 };

    if (!genKeys) {
        if ((int)(sizeof(KEYS) / sizeof(*KEYS)) < (nextKey + 1)) {
            missingKey();
        }
        Bits_memcpyConst(address.key, KEYS[nextKey], 32);
        if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)
            && (mostSignificantAddressSpaceByte == -1
                || address.ip6.bytes[8] == mostSignificantAddressSpaceByte))
        {
            nextKey++;
            uint8_t publicKeyHex[65];
            Hex_encode(publicKeyHex, 65, address.key, 32);
            printf("created new key: [%s]\n", publicKeyHex);

            address.path = path;
            return Allocator_clone(alloc, &address);
        } else {
            uint8_t publicKeyHex[65];
            Hex_encode(publicKeyHex, 65, address.key, 32);
            printf("bad key: [%s]\n", publicKeyHex);
            if (address.ip6.ints.three) {
                uint8_t printedAddr[40];
                AddrTools_printIp(printedAddr, address.ip6.bytes);
                printf("addr: [%s]\n", printedAddr);
            }
                missingKey();
        }
    }

    for (;;) {
        Random_bytes(rand, address.key, 32);
        // Brute force for keys until one matches FC00:/8
        if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)
            && (mostSignificantAddressSpaceByte == -1
                || address.ip6.bytes[8] == mostSignificantAddressSpaceByte))
        {

            uint8_t publicKeyHex[65];
            Hex_encode(publicKeyHex, 65, address.key, 32);
            printf("created new key: [%s]\n", publicKeyHex);

            address.path = path;
            return Allocator_clone(alloc, &address);
        }
    }
}

static struct Address* randomIp(int* hops)
{
    return createAddress(-1, hops);
}

// This creates a random address which is a peer
static struct Address* randomAddress()
{
    return randomIp((int[]){0,1}/*0x13*/);
}