Exemplo n.º 1
0
LONGBOW_TEST_CASE(Global, metisMessage_Copy)
{
    char message_str[] = "\x00Once upon a time, in a stack far away, a dangling pointer found its way to the top of the heap.";

    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    assertNotNull(message, "Got null from metisMessage_CreateFromBuffer");
    assertTrue(message->refcount == 1, "Incorrect refcount, expected %u got %u", 1, message->refcount);

    MetisMessage *copy = metisMessage_Acquire(message);
    assertTrue(message->refcount == 2, "Incorrect refcount, expected %u got %u", 2, message->refcount);

    metisMessage_Release(&message);
    assertTrue(copy->refcount == 1, "Incorrect refcount, expected %u got %u", 1, message->refcount);

    metisMessage_Release(&copy);

    assertTrue(parcMemory_Outstanding() == 0, "Memory balance should be zero after destroying last copy, got %u", parcMemory_Outstanding());
}
Exemplo n.º 2
0
LONGBOW_TEST_CASE(Global, metisMessage_ReadFromBuffer)
{
    char message_str[] = "\x00Once upon a time, in a stack far away, a dangling pointer found its way to the top of the heap.";

    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_ReadFromBuffer(1, 2, buff, sizeof(message_str), logger);
    metisLogger_Release(&logger);

    assertNotNull(message, "Got null from metisMessage_CreateFromBuffer");

    assertTrue(parcEventBuffer_GetLength(message->messageBytes) == sizeof(message_str),
               "Length of internal buffer wrong, expected %zu got %zu",
               sizeof(message_str),
               parcEventBuffer_GetLength(message->messageBytes));

    uint8_t *p = parcEventBuffer_Pullup(message->messageBytes, sizeof(message_str));
    assertTrue(memcmp(p, message_str, sizeof(message_str)) == 0, "Internal buffer contents does not match test");
    assertTrue(message->ingressConnectionId == 1, "IngressConnectionId wrong, expected %d got %u", 1, message->ingressConnectionId);
    assertTrue(message->receiveTime == 2, "receiveTime wrong, expected %u got %" PRIu64, 2, message->receiveTime);
    assertTrue(parcEventBuffer_GetLength(buff) == 0, "Origin buffer not drained, expected 0, got %zu", parcEventBuffer_GetLength(buff));

    metisMessage_Release(&message);
    parcEventBuffer_Destroy(&buff);
}
Exemplo n.º 3
0
/*
 * We've reach the END fragment of the reassembly buffer.
 * 1) Make a metis message out of the reassembly buffer,
 * 2) put the message in the receive queue (discard if queue full)
 * 3) allocate a new reassembly buffer
 * 4) reset the parser
 */
static void
_finalizeReassemblyBuffer(MetisHopByHopFragmenter *fragmenter)
{
    // This takes ownership of fragmenter->currentReceiveBuffer
    MetisMessage *reassembled = metisMessage_CreateFromBuffer(fragmenter->currentReceiveBufferIngressId,
                                                              fragmenter->currentReceiveBufferStartTicks,
                                                              fragmenter->currentReceiveBuffer,
                                                              fragmenter->logger);

    if (reassembled) {
        bool success = parcRingBuffer1x1_Put(fragmenter->receiveQueue, reassembled);
        if (success) {
            metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug, __func__,
                            "Fragmenter %p putting reassembed message %p in receive queue",
                            (void *) fragmenter, (void *) reassembled);
        } else {
            metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Error, __func__,
                            "Fragmenter %p failed to put reassembled message in receive queue, dropping",
                            (void *) fragmenter);

            metisMessage_Release(&reassembled);
        }

        fragmenter->currentReceiveBuffer = parcEventBuffer_Create();
    } else {
        metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Warning, __func__,
                        "Fragmenter %p failed to parse reassembled packet to MetisMessage, dropping",
                        (void *) fragmenter);
    }

    _resetParser(fragmenter);
}
Exemplo n.º 4
0
LONGBOW_TEST_CASE(Global, metisMessage_Append)
{
    char message_str[] = "\x00Once upon a time ...";

    PARCEventBuffer *buffer = parcEventBuffer_Create();
    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    int result = metisMessage_Append(buffer, message);

    assertTrue(result == 0, "Got error from metisMessage_Append");
    metisLogger_Release(&logger);
    metisMessage_Release(&message);
    parcEventBuffer_Destroy(&buffer);
}
Exemplo n.º 5
0
MetisGenericEther *
metisGenericEther_Create(MetisForwarder *metis, const char *deviceName, uint16_t etherType)
{
    assertNotNull(metis, "Parameter metis must be non-null");

    // The Darwin generic ether allows a NULL device name, it is used in the unit tests.

    MetisGenericEther *ether = NULL;

    if (metisEthernet_IsValidEthertype(etherType)) {
        ether = parcObject_CreateInstance(MetisGenericEther);
        ether->ethertype = etherType;
        ether->logger = metisLogger_Acquire(metisForwarder_GetLogger(metis));
        ether->etherSocket = -1; // invalid valid
        ether->workBuffer = parcEventBuffer_Create();
        ether->macAddress = NULL;
        ether->mtu = metisSystem_InterfaceMtu(metis, deviceName);

        _darwinEthernet_SetInterfaceAddress(ether, deviceName);

        bool success = _darwinEthernet_SetupReceive(ether, deviceName);

        if (success) {
            if (metisLogger_IsLoggable(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Info)) {
                char *str = parcBuffer_ToHexString(ether->macAddress);
                metisLogger_Log(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Info, __func__,
                                "GenericEther %p created on device %s (%s) for ethertype 0x%04x fd %d bufferLength %u mtu %u",
                                (void *) ether, deviceName, str, etherType, ether->etherSocket, ether->etherBufferLength, ether->mtu);
                parcMemory_Deallocate((void **) &str);
            }
        } else {
            if (metisLogger_IsLoggable(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Error)) {
                metisLogger_Log(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Error, __func__,
                                "GenericEther failed to created on device %s for ethertype 0x%04x",
                                deviceName, etherType);
            }

            // this will also null ether
            metisGenericEther_Release(&ether);
        }

        assertTrue(ether->etherBufferLength < 65536, "Buffer length way too big, expected less than 65536 got %u", ether->etherBufferLength);
    } else {
        if (metisLogger_IsLoggable(metisForwarder_GetLogger(metis), MetisLoggerFacility_IO, PARCLogLevel_Error)) {
            metisLogger_Log(metisForwarder_GetLogger(metis), MetisLoggerFacility_IO, PARCLogLevel_Error, __func__,
                            "GenericEther failed to created on device %s for ethertype 0x%04x, invalid ethertype",
                            deviceName, etherType);
        }
    }

    return ether;
}
Exemplo n.º 6
0
LONGBOW_TEST_CASE(Global, metisMessage_HasInterestLifetime)
{
    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, metisTestDataV1_Interest_AllFields, sizeof(metisTestDataV1_Interest_AllFields));
    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    assertTrue(metisMessage_HasInterestLifetime(message), "Should have returned true for interest lifetime");

    metisMessage_Release(&message);
}
Exemplo n.º 7
0
LONGBOW_TEST_CASE(Global, metisMessage_GetInterestLifetimeTicks)
{
    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, metisTestDataV1_Interest_AllFields, sizeof(metisTestDataV1_Interest_AllFields));
    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    // don't check actual value.  It will vary based on METISHZ and rouding errors due to integer math
    MetisTicks ticks = metisMessage_GetInterestLifetimeTicks(message);
    assertTrue(ticks > 0, "Should have gotten positive value for interest lifetime ticks");

    metisMessage_Release(&message);
}
Exemplo n.º 8
0
LONGBOW_TEST_CASE(Global, metisMessage_Create_InterestV1)
{
    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, metisTestDataV1_Interest_AllFields, sizeof(metisTestDataV1_Interest_AllFields));
    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    assertNotNull(message, "Got null from metisMessage_CreateFromBuffer");
    assertTrue(message->ingressConnectionId == 1, "IngressConnectionId wrong, expected %d got %u", 1, message->ingressConnectionId);
    assertTrue(message->receiveTime == 2, "receiveTime wrong, expected %u got %" PRIu64, 2, message->receiveTime);

    metisMessage_Release(&message);
}
Exemplo n.º 9
0
LONGBOW_TEST_CASE(Global, metisMessage_CreateFromBuffer_BadMessage)
{
    // Bad version
    char message_str[] = "\xFFOnce upon a time, in a stack far away, a dangling pointer found its way to the top of the heap.";

    printf("metisMessage_CreateFromBuffer_BadMessage attempting to process a bad message which should report an error:\n");
    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    assertNull(message, "Got null from metisMessage_CreateFromBuffer");
}
Exemplo n.º 10
0
LONGBOW_TEST_CASE(Global, metisMessage_Length)
{
    char message_str[] = "\x00Once upon a time, in a stack far away, a dangling pointer found its way to the top of the heap.";

    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    assertNotNull(message, "Got null from metisMessage_CreateFromBuffer");
    size_t length = metisMessage_Length(message);
    assertTrue(length == sizeof(message_str), "Wrong length, expected %zu got %zu", sizeof(message_str), length);
    metisMessage_Release(&message);
}
Exemplo n.º 11
0
LONGBOW_TEST_CASE(Global, metisMessage_GetReceiveTime)
{
    char message_str[] = "\x00Once upon a time, in a stack far away, a dangling pointer found its way to the top of the heap.";

    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    metisLogger_Release(&logger);

    assertNotNull(message, "Got null from metisMessage_CreateFromBuffer");
    MetisTicks time = metisMessage_GetReceiveTime(message);

    assertTrue(time == 2, "Wrong receive time, expected %u got %" PRIu64, 2, time);
    metisMessage_Release(&message);
}
Exemplo n.º 12
0
MetisHopByHopFragmenter *
metisHopByHopFragmenter_Create(MetisLogger *logger, unsigned mtu)
{
    MetisHopByHopFragmenter *fragmenter = parcMemory_Allocate(sizeof(MetisHopByHopFragmenter));
    if (fragmenter) {
        fragmenter->nextReceiveFragSequenceNumber = 0;
        fragmenter->nextSendFragSequenceNumber = 0;

        fragmenter->logger = metisLogger_Acquire(logger);
        fragmenter->mtu = mtu;
        fragmenter->receiveQueueCapacity = 128;  // this is a many-to-one queue, so not too big
        fragmenter->sendQueueCapacity = 2048;    // this is a one-to-many queue, so bigger (e.g. 64 KB in to 1KB payloads)
        fragmenter->receiveQueue = parcRingBuffer1x1_Create(fragmenter->receiveQueueCapacity, _ringBufferDestroyer);
        fragmenter->sendQueue = parcRingBuffer1x1_Create(fragmenter->sendQueueCapacity, _ringBufferDestroyer);
        fragmenter->currentReceiveBuffer = parcEventBuffer_Create();
        fragmenter->parserState = _ParserState_Idle;
    }
    return fragmenter;
}
Exemplo n.º 13
0
LONGBOW_TEST_CASE(Global, metisMessage_Write)
{
    char message_str[] = "\x00Once upon a time ...";

    PARCEventScheduler *scheduler = parcEventScheduler_Create();
    PARCEventQueue *queue = parcEventQueue_Create(scheduler, -1, PARCEventQueueOption_CloseOnFree);

    PARCEventBuffer *buff = parcEventBuffer_Create();
    parcEventBuffer_Append(buff, message_str, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromBuffer(1, 2, buff, logger);
    int result = metisMessage_Write(queue, message);

    assertTrue(result == 0, "Got error from metisMessage_Write");

    // buff is deallocated by metisMessage_Release
    metisLogger_Release(&logger);
    metisMessage_Release(&message);
    parcEventQueue_Destroy(&queue);
    parcEventScheduler_Destroy(&scheduler);
}