Exemple #1
0
void NetDev_addAddress(const char* ifName,
                       struct Sockaddr* sa,
                       int prefixLen,
                       struct Log* logger,
                       struct Except* eh)
{
    int addrFam = Sockaddr_getFamily(sa);

    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 4096);
    char* printedAddr = Sockaddr_print(sa, alloc);
    if (addrFam != Sockaddr_AF_INET && addrFam != Sockaddr_AF_INET6) {
        Except_throw(eh, "Unknown address type for address [%s]", printedAddr);
    }

    int prefixMax = (addrFam == Sockaddr_AF_INET6) ? 128 : 32;
    if (prefixLen < 0 || prefixLen > prefixMax) {
        Except_throw(eh, "prefixLen [%d] must be greater than 0 and less than %d",
                     prefixLen, prefixMax);
    }

    void* addr;
    int len = Sockaddr_getAddress(sa, &addr);
    if (len < 0 || len != prefixMax / 8) {
        Except_throw(eh, "Invalid sockaddr [%s]", printedAddr);
    }

    Log_info(logger, "Setting IP address [%s/%d] on interface [%s]",
             printedAddr, prefixLen, ifName);

    NetPlatform_addAddress(ifName, addr, prefixLen, addrFam, logger, eh);
}
struct Message* InterfaceWaiter_waitForData(struct Interface* iface,
                                            struct event_base* eventBase,
                                            struct Allocator* alloc,
                                            struct Except* eh)
{
    struct Context ctx = {
        .eventBase = eventBase,
        .exceptionHandler = eh,
        .alloc = alloc
    };

    struct Allocator* tempAlloc;
    BufferAllocator_STACK(tempAlloc, 512);

    iface->receiverContext = &ctx;
    iface->receiveMessage = receiveMessage;

    ctx.timeout = Timeout_setTimeout(timeout, &ctx, 2000, eventBase, tempAlloc);
    event_base_dispatch(eventBase);

    iface->receiveMessage = NULL;

    Assert_true(ctx.message);
    return ctx.message;
}
int main()
{
    uint16_t randomShorts[8192];
    uint16_t out[8192];
    struct ReplayProtector rp = {0,0};

    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 1024);

    struct Random* rand = Random_new(alloc, NULL, NULL);

    Random_bytes(rand, (uint8_t*)randomShorts, sizeof(randomShorts));

    uint32_t outIdx = 0;
    for (uint32_t i = 0; i < 1024; i++) {
        if (ReplayProtector_checkNonce((randomShorts[i] % (i + 20)), &rp)) {
            out[outIdx] = (randomShorts[i] % (i + 20));
            outIdx++;
        }
    }

    for (uint32_t i = 0; i < outIdx; i++) {
        for (uint32_t j = i + 1; j < outIdx; j++) {
            Assert_always(out[i] != out[j]);
        }
    }

    return 0;
}
Exemple #4
0
struct Message* InterfaceWaiter_waitForData(struct Interface* iface,
                                            struct EventBase* eventBase,
                                            struct Allocator* alloc,
                                            struct Except* eh)
{
    struct Context ctx = {
        .eventBase = eventBase,
        .alloc = alloc
    };

    struct Allocator* tempAlloc;
    BufferAllocator_STACK(tempAlloc, 512);

    iface->receiverContext = &ctx;
    iface->receiveMessage = receiveMessage;

    ctx.timeout = Timeout_setTimeout(timeout, &ctx, 2000, eventBase, tempAlloc);
    EventBase_beginLoop(eventBase);

    iface->receiveMessage = NULL;

    Allocator_free(tempAlloc);
    if (ctx.timedOut) {
        Except_raise(eh, InterfaceWaiter_waitForData_TIMEOUT,
                     "InterfaceWaiter Timed out waiting for data.");
    }

    Assert_true(ctx.message);
    return ctx.message;
}
Exemple #5
0
static void listConnections(Dict* args, void* vcontext, String* txid)
{
    struct Context* context = vcontext;
    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 1024);
    List* l = NULL;
    for (int i = 0; i < (int)context->ipTun->connectionList.count; i++) {
        l = List_addInt(l, context->ipTun->connectionList.connections[i].number, alloc);
    }
    Dict resp = Dict_CONST(
        String_CONST("connections"), List_OBJ(l), Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), NULL
    ));
    Admin_sendMessage(&resp, txid, context->admin);
}
Exemple #6
0
void NetDev_addAddress(const char* ifName,
                       struct Sockaddr* sa,
                       struct Log* logger,
                       struct Except* eh)
{
    int addrFam;
    char* printedAddr;
    void* addr;
    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 4096);

    checkAddressAndPrefix(sa, &addrFam, &printedAddr, &addr, alloc, eh);

    Log_info(logger, "Setting IP address [%s/%d] on interface [%s]",
             printedAddr, sa->prefix, ifName);

    NetPlatform_addAddress(ifName, addr, sa->prefix, addrFam, logger, alloc, eh);
}
Exemple #7
0
int main()
{
    struct Allocator* stackAlloc;
    BufferAllocator_STACK(stackAlloc, 2048);
    struct Random* rand = Random_new(stackAlloc, NULL, NULL);

    for (int cycles = 0; cycles < CYCLES; cycles++) {
        struct Allocator* alloc = MallocAllocator_new(1<<18);
        struct Map_OfLongsByInteger* map = Map_OfLongsByInteger_new(alloc);
        uint32_t size;
        Random_bytes(rand, (uint8_t*) &size, 4);
        size = (size % 4096) + 101;

        uint32_t key = 3;
        uint64_t val = 4;
        for (uint32_t i = 0; i < size; i++) {
            Map_OfLongsByInteger_put(&key, &val, map);
            key += val >> 13 ^ size << 19;
            val += key >> 19 ^ i << 13;
        }

        // If a key is duplicated, the entry will br replaced.
        size = map->count;

        for (uint32_t i = size - 1; i > size - 100; i--) {
            int index = map->keys[i] % size;
            uint32_t handle = map->handles[index];
            if (index != Map_OfLongsByInteger_indexForHandle(handle, map)) {
                uint32_t num = 0;
                for (int i = 0; i < (int)map->count; i++) {
                    if (num > map->handles[i]) {
                        Assert_true(!"map out of order");
                    }
                    num = map->handles[i];
                }
                printf("failed to find the correct index for the handle "
                       "handle[%u], index[%u], indexForHandle[%u]\n",
                       handle, index, Map_OfLongsByInteger_indexForHandle(handle, map));
                Assert_true(false);
            }
        }
        Allocator_free(alloc);
    }
}
Exemple #8
0
int main()
{
    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 512);
    struct Random* rand = Random_new(alloc, NULL);

    uint8_t bytes[32];
    Random_bytes(rand, bytes, 32);

    uint8_t base32[64];
    Bits_memset(base32, 0, 64);

    Assert_always(Base32_encode(base32, 64, bytes, 32) == 52);

    //printf("base32 encoded: %s\n", base32);

    uint8_t bytes2[32];
    Assert_always(Base32_decode(bytes2, 32, base32, 52) == 32);

    Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0);
}
Exemple #9
0
static void showConn(struct IpTunnel_Connection* conn, String* txid, struct Admin* admin)
{
    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 1024);
    Dict* d = Dict_new(alloc);

    char ip6[40];
    if (!Bits_isZero(conn->connectionIp6, 16)) {
        Assert_always(evutil_inet_ntop(AF_INET6, conn->connectionIp6, ip6, 40));
        Dict_putString(d, String_CONST("ip6Address"), String_CONST(ip6), alloc);
    }

    char ip4[16];
    if (!Bits_isZero(conn->connectionIp4, 4)) {
        Assert_always(evutil_inet_ntop(AF_INET, conn->connectionIp4, ip4, 16));
        Dict_putString(d, String_CONST("ip4Address"), String_CONST(ip4), alloc);
    }

    Dict_putString(d, String_CONST("key"), Key_stringify(conn->header.nodeKey, alloc), alloc);
    Dict_putInt(d, String_CONST("outgoing"), conn->isOutgoing, alloc);

    Admin_sendMessage(d, txid, admin);
}
Exemple #10
0
/** @return a string representing the address and port to connect to. */
static String* initAngel(int fromAngel,
                         int toAngel,
                         int corePipes[2][2],
                         struct PipeInterface** piOut,
                         struct EventBase* eventBase,
                         struct Log* logger,
                         struct Allocator* alloc,
                         struct Random* rand)
{
    #define TO_CORE (corePipes[0][1])
    #define FROM_CORE (corePipes[1][0])
    #define TO_ANGEL_AS_CORE (corePipes[1][1])
    #define FROM_ANGEL_AS_CORE (corePipes[0][0])

    Dict core = Dict_CONST(
        String_CONST("fromCore"), Int_OBJ(FROM_CORE), Dict_CONST(
        String_CONST("toCore"), Int_OBJ(TO_CORE), NULL
    ));
    Dict admin = Dict_CONST(
        String_CONST("bind"), String_OBJ(String_CONST("127.0.0.1")), Dict_CONST(
        String_CONST("core"), Dict_OBJ(&core), Dict_CONST(
        String_CONST("pass"), String_OBJ(String_CONST("abcd")), NULL
    )));
    Dict message = Dict_CONST(
        String_CONST("admin"), Dict_OBJ(&admin), NULL
    );

    struct Allocator* tempAlloc;
    BufferAllocator_STACK(tempAlloc, 1024);

    #define BUFFER_SZ 1023
    uint8_t buff[BUFFER_SZ + 1] = {0};
    struct Writer* w = ArrayWriter_new(buff, BUFFER_SZ, tempAlloc);
    StandardBencSerializer_get()->serializeDictionary(w, &message);

    Log_info(logger, "Writing intial configuration to angel on [%d] config: [%s]", toAngel, buff);
    write(toAngel, buff, w->bytesWritten(w));

    // This is angel->core data, we can throw this away.
    //Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);
    //Log_info(logger, "Init message from angel to core: [%s]", buff);
    Bits_memset(buff, 0, BUFFER_SZ);

    struct PipeInterface* pi =
        PipeInterface_new(FROM_ANGEL_AS_CORE, TO_ANGEL_AS_CORE, eventBase, logger, alloc, rand);
    *piOut = pi;

    Log_info(logger, "PipeInterface [%p] is now ready.", (void*)pi);

    // Make sure the angel sends data to the core.
    InterfaceWaiter_waitForData(&pi->generic, eventBase, alloc, NULL);

    // Send response on behalf of core.
    char coreToAngelResponse[128] = "           PADDING              "
        "\xff\xff\xff\xff"
        "d"
          "5:error" "4:none"
        "e";

    char* start = strchr(coreToAngelResponse, '\xff');
    struct Message m = {
        .bytes = (uint8_t*) start,
        .length = strlen(start),
        .padding = start - coreToAngelResponse
    };
    pi->generic.sendMessage(&m, &pi->generic);

    // This is angel->client data, it will tell us which port was bound.
    Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);

    printf("Response from angel to client: [%s]\n", buff);

    struct Reader* reader = ArrayReader_new(buff, BUFFER_SZ, tempAlloc);
    Dict configStore;
    Dict* config = &configStore;
    Assert_true(!StandardBencSerializer_get()->parseDictionary(reader, tempAlloc, config));

    Dict* responseAdmin = Dict_getDict(config, String_CONST("admin"));
    String* bind = Dict_getString(responseAdmin, String_CONST("bind"));
    Assert_true(bind);

    return String_clone(bind, alloc);
}

/**
 * This spawns itself as the Angel process which spawns itself again as the core process.
 * The "core process" pipes all of its inputs back to the originating process
 */

struct AdminTestFramework* AdminTestFramework_setUp(int argc, char** argv)
{
    if (argc > 1 && !strcmp("angel", argv[1])) {
        exit(AngelInit_main(argc, argv));
    }

    struct Allocator* alloc = CanaryAllocator_new(MallocAllocator_new(1<<20), NULL);

    struct Writer* logwriter = FileWriter_new(stdout, alloc);
    Assert_always(logwriter);
    struct Log* logger = WriterLog_new(logwriter, alloc);

    struct EventBase* eventBase = EventBase_new(alloc);
    struct Random* rand = Random_new(alloc, NULL);

    int fromAngel;
    int toAngel;
    int corePipes[2][2];
    if (Pipe_createUniPipe(corePipes[0]) || Pipe_createUniPipe(corePipes[1])) {
        Except_raise(NULL, -1, "Failed to create pipes [%s]", Errno_getString());
    }
    spawnAngel(&fromAngel, &toAngel);

    struct PipeInterface* pi;
    String* addrStr =
        initAngel(fromAngel, toAngel, corePipes, &pi, eventBase, logger, alloc, rand);

    Log_info(logger, "Angel initialized.");

    String* password = String_new("abcd", alloc);
    struct Admin* admin =
        Admin_new(&pi->generic, alloc, logger, eventBase, password);


    // Now setup the client.

    struct sockaddr_storage addr;
    int addrLen = sizeof(struct sockaddr_storage);
    Bits_memset(&addr, 0, sizeof(struct sockaddr_storage));
    Assert_true(!evutil_parse_sockaddr_port(addrStr->bytes, (struct sockaddr*) &addr, &addrLen));

    struct AdminClient* client =
        AdminClient_new((uint8_t*) &addr, addrLen, password, eventBase, logger, alloc);

    Assert_always(client);

    return alloc->clone(sizeof(struct AdminTestFramework), alloc, &(struct AdminTestFramework) {
        .admin = admin,
        .client = client,
        .alloc = alloc,
        .eventBase = eventBase,
        .logger = logger,
        .addr = alloc->clone(addrLen, alloc, &addr),
        .addrLen = addrLen,
        .angelInterface = &pi->generic
    });
}