Example #1
0
// There's a bit too much going on in this function, need to break it
// apart for testability and style.
static MetisPITVerdict
_metisStandardPIT_ReceiveInterest(MetisPIT *generic, MetisMessage *interestMessage)
{
    assertNotNull(generic, "Parameter pit must be non-null");
    assertNotNull(interestMessage, "Parameter interestMessage must be non-null");

    MetisStandardPIT *pit = metisPIT_Closure(generic);

    MetisPitEntry *pitEntry = metisMatchingRulesTable_Get(pit->table, interestMessage);

    if (pitEntry) {
        // has it expired?
        MetisTicks now = metisForwarder_GetTicks(pit->metis);
        if (now < metisPitEntry_GetExpiryTime(pitEntry)) {
            // what should we do about extending the lifetime? (case 819)

            _metisPIT_ExtendLifetime(pit, pitEntry, interestMessage);

            // Is the reverse path already in the PIT entry?
            if (_metisPIT_IngressSetContains(pitEntry, metisMessage_GetIngressConnectionId(interestMessage))) {
                // It is already in the PIT entry, so this is a retransmission, so forward it.

                if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) {
                    metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__,
                                    "Message %p existing entry (expiry %" PRIu64 ") and reverse path, forwarding",
                                    (void *) interestMessage,
                                    metisPitEntry_GetExpiryTime(pitEntry));
                }

                return MetisPITVerdict_Forward;
            }

            // It is in the PIT but this is the first interest for the reverse path
            metisPitEntry_AddIngressId(pitEntry, metisMessage_GetIngressConnectionId(interestMessage));

            if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) {
                metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__,
                                "Message %p existing entry (expiry %" PRIu64 ") and reverse path is new, aggregate",
                                (void *) interestMessage,
                                metisPitEntry_GetExpiryTime(pitEntry));
            }

            return MetisPITVerdict_Aggregate;
        }

        // it's an old entry, remove it
        metisMatchingRulesTable_RemoveFromBest(pit->table, interestMessage);
    }

    _metisPIT_StoreInTable(pit, interestMessage);

    return MetisPITVerdict_Forward;
}
Example #2
0
void
metisConfiguration_Receive(MetisConfiguration *config, MetisMessage *message)
{
    assertNotNull(config, "Parameter config must be non-null");
    assertNotNull(message, "Parameter message must be non-null");
    assertTrue(metisMessage_GetType(message) == MetisMessagePacketType_Control,
               "Message must be type CPI, expected %02x got %02x",
               MetisMessagePacketType_Control, metisMessage_GetType(message));

    CCNxControl *control = metisMessage_CreateControlMessage(message);
    unsigned ingressId = metisMessage_GetIngressConnectionId(message);

    if (metisLogger_IsLoggable(config->logger, MetisLoggerFacility_Config, PARCLogLevel_Debug)) {
        char *str = parcJSON_ToCompactString(ccnxControl_GetJson(control));
        metisLogger_Log(config->logger, MetisLoggerFacility_Config, PARCLogLevel_Debug, __func__,
                        "%s received %s\n", __func__, str);
        parcMemory_Deallocate((void **) &str);
    }

    CCNxControl *response = _processControl(config, control, ingressId);
    metisConfiguration_SendResponse(config, response, ingressId);
    ccnxControl_Release(&response);

    ccnxControl_Release(&control);
    metisMessage_Release(&message);
}
Example #3
0
/*
 * Parser is in Idle state.  We can only accept a B or BE frame.
 * 1) If B frame:
 * 1a) append to current receive buffer
 * 1b) set parser state to Busy
 * 1c) set the currentReceiveBufferStartTicks
 * 1d) set the currentReceiveBufferIngressId
 * 2) If BE frame, do B actions and finalize it (side effect: will reset state to Idle)
 * 3) Otherwise ignore it
 *
 * Precondition: You know that the parser is in the Idle state
 */
static void
_receiveInIdleState(MetisHopByHopFragmenter *fragmenter, const MetisMessage *message, const _HopByHopHeader *fixedHeader)
{
    trapUnexpectedStateIf(fragmenter->parserState != _ParserState_Idle,
                          "Parser in wrong state, expected %d got %d",
                          _ParserState_Idle, fragmenter->parserState);

    if (_hopByHopHeader_GetBFlag(fixedHeader)) {
        // start a new packet
        fragmenter->currentReceiveBufferStartTicks = metisMessage_GetReceiveTime(message);
        fragmenter->currentReceiveBufferIngressId = metisMessage_GetIngressConnectionId(message);
        fragmenter->parserState = _ParserState_Busy;

        _appendFragmentToReassemblyBuffer(fragmenter, message);

        if (_hopByHopHeader_GetEFlag(fixedHeader)) {
            // it is also the last fragment
            _finalizeReassemblyBuffer(fragmenter);
        }
    } else if (_hopByHopHeader_GetIFlag(fixedHeader)) {
        // nothing to do
        metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug, __func__,
                        "Fragmenter %p idle frame, ignorning",
                        (void *) fragmenter);
    } else {
        // nothing we can do with this frame
        metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Warning, __func__,
                        "Fragmenter %p received bad header flags (0x%02X), ignorning",
                        (void *) fragmenter, _hopByHopHeader_GetFlags(fixedHeader));
    }
}
Example #4
0
LONGBOW_TEST_CASE(Global, metisMessage_GetConnectionId)
{
    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");
    unsigned connid = metisMessage_GetIngressConnectionId(message);

    assertTrue(connid == 1, "Wrong length, expected %u got %u", 1, connid);
    metisMessage_Release(&message);
}
Example #5
0
static void
_metisPIT_StoreInTable(MetisStandardPIT *pit, MetisMessage *interestMessage)
{
    MetisMessage *key = metisMessage_Acquire(interestMessage);

    MetisTicks expiryTime = _metisPIT_CalculateLifetime(pit, interestMessage);

    MetisPitEntry *pitEntry = metisPitEntry_Create(key, expiryTime);
    // this is done in metisPitEntry_Create
    //    metisPitEntry_AddIngressId(pitEntry, metisMessage_GetIngressConnectionId(interestMessage));

    metisMatchingRulesTable_AddToBestTable(pit->table, key, pitEntry);

    if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) {
        metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__,
                        "Message %p added to PIT (expiry %" PRIu64 ") ingress %u",
                        (void *) interestMessage,
                        metisPitEntry_GetExpiryTime(pitEntry),
                        metisMessage_GetIngressConnectionId(interestMessage));
    }
}