예제 #1
0
static uint64_t getPath(int* hops)
{
    int i;
    uint64_t out = 0;
    for (i = 0; hops[i] != 1; i++) ;
    for (; i >= 0; i--) {
        int bits = NumberCompress_bitsUsedForNumber(hops[i]);
        out <<= bits;
        out |= NumberCompress_getCompressed(hops[i], bits);
    }
    return out;
}
예제 #2
0
/**
 * Get the label for a particular destination from a given source.
 * This needs to be called before handing out a label because if a source interface is
 * represented using more bits than the destination interface, the destination interface
 * must be padded out so that the switch will find the source and destination labels compatable.
 *
 * @param target_be the label for the location to send to in big endian.
 * @param whoIsAsking_be the label for the node which we are sending the target to in big endian.
 * @return the modified target for that node in big endian.
 */
uint64_t LabelSplicer_getLabelFor(uint64_t target_be, uint64_t whoIsAsking_be)
{
    uint64_t target = Endian_bigEndianToHost64(target_be);
    uint64_t whoIsAsking = Endian_bigEndianToHost64(whoIsAsking_be);

    uint32_t targetBits = NumberCompress_bitsUsedForLabel(target);
    uint32_t whoIsAskingBits = NumberCompress_bitsUsedForLabel(whoIsAsking);

    if (targetBits >= whoIsAskingBits) {
        return target_be;
    }

    uint32_t targetIfaceNum = NumberCompress_getDecompressed(target, targetBits);

    uint64_t out = ((target & (UINT64_MAX << targetBits)) << (whoIsAskingBits - targetBits))
        | NumberCompress_getCompressed(targetIfaceNum, whoIsAskingBits);

    return Endian_hostToBigEndian64(out);
}
예제 #3
0
static int reconnectionNewEndpointTest(struct InterfaceController* ifController,
                                       uint8_t* pk,
                                       struct Message** fromSwitchPtr,
                                       struct Allocator* alloc,
                                       struct EventBase* eventBase,
                                       struct Log* logger,
                                       struct Interface* routerIf,
                                       struct Random* rand)
{
    struct Message* message;
    struct Interface iface = {
        .sendMessage = messageFromInterface,
        .senderContext = &message,
        .allocator = alloc
    };

    uint8_t* buffer = Allocator_malloc(alloc, 512);

    struct Message* outgoing =
        &(struct Message) { .length = 0, .padding = 512, .bytes = buffer + 512 };

    struct CryptoAuth* externalCa = CryptoAuth_new(alloc, NULL, eventBase, logger, rand);
    struct Interface* wrapped = CryptoAuth_wrapInterface(&iface, pk, NULL, false, "", externalCa);
    CryptoAuth_setAuth(String_CONST("passwd"), 1, wrapped);

    struct Interface icIface = {
        .allocator = alloc,
        .sendMessage = messageFromInterface,
        .senderContext = &message
    };

    InterfaceController_registerPeer(ifController, NULL, NULL, true, false, &icIface);

    uint8_t hexBuffer[1025];

    for (int i = 0; i < 4; i++) {

        outgoing->length = 0;
        outgoing->padding = 512;
        outgoing->bytes = buffer + 512;
        Message_shift(outgoing, 12, NULL);
        Bits_memcpyConst(outgoing->bytes, "hello world", 12);

        Message_shift(outgoing, SwitchHeader_SIZE, NULL);
        Bits_memcpyConst(outgoing->bytes, (&(struct SwitchHeader) {
            .label_be = Endian_hostToBigEndian64(1),
            .lowBits_be = 0
        }), SwitchHeader_SIZE);

        wrapped->sendMessage(outgoing, wrapped);

        *fromSwitchPtr = NULL;

        icIface.receiveMessage(outgoing, &icIface);

        message = *fromSwitchPtr;
        Assert_true(message);
        Assert_true(message->length == 24);

        Hex_encode(hexBuffer, 1025, message->bytes, message->length);
        printf("%s\n", hexBuffer);

        // Need to bounce the packets back when connecting after the first try.
        // This is needed to establish the CryptoAuth session and make the InterfaceController
        // merge the endpoints.
        if (i > 0) {
            // Reverse the bits to reverse the path:
            uint64_t path;
            Bits_memcpyConst(&path, message->bytes, 8);
            path = Bits_bitReverse64(path);
            Bits_memcpyConst(message->bytes, &path, 8);

            printf("sending back response.\n");
            routerIf->receiveMessage(message, routerIf);
            printf("forwarding response to external cryptoAuth.\n");
            iface.receiveMessage(message, &iface);
            printf("forwarded.\n");
        } else {
            printf("not responding because we don't want to establish a connection yet.\n");
        }
    }

    // check everything except the label
    Assert_true(!CString_strcmp((char*)hexBuffer+16, "0000000068656c6c6f20776f726c6400"));
    // check label: make sure the interface has been switched back into position 0.
    uint64_t label_be;
    Hex_decode((uint8_t*) &label_be, 8, hexBuffer, 16);
    uint64_t rev_label = Bits_bitReverse64(Endian_bigEndianToHost64(label_be));
    // check label is decoded to 0
    Assert_true(0 == NumberCompress_getDecompressed(rev_label,
                                                      NumberCompress_bitsUsedForLabel(rev_label)));
    // check no other bits are set
    uint64_t out = NumberCompress_getCompressed(0, NumberCompress_bitsUsedForLabel(rev_label));
    Assert_true(rev_label == out);
    return 0;
}
예제 #4
0
static uint64_t routeToInterface(uint32_t number)
{
    uint32_t bits = NumberCompress_bitsUsedForNumber(number);
    return (1 << bits) | NumberCompress_getCompressed(number, bits);
}