예제 #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;
}
예제 #2
0
static MetisTicks
_metisPIT_CalculateLifetime(MetisStandardPIT *pit, MetisMessage *interestMessage)
{
    // Should use the lifetime from the interest (case 694)
    uint64_t interestLifetimeTicks = 0;

    if (metisMessage_HasInterestLifetime(interestMessage)) {
        interestLifetimeTicks = metisMessage_GetInterestLifetimeTicks(interestMessage);
    } else {
        interestLifetimeTicks = metisForwarder_NanosToTicks(4000000000ULL);
    }

    MetisTicks expiryTime = metisForwarder_GetTicks(pit->metis) + interestLifetimeTicks;
    return expiryTime;
}
예제 #3
0
/**
 * @function single_read
 * @abstract Read at most 1 message from the network
 * @discussion
 *   If a complete message is ready on the input buffer, will allocate and return it.
 *
 *   This function manipulates the stream->nextMessageLength.  (1) Initializes with nextMessageLength = 0,
 *   which means we have not started parsing a packet.  (2) After reading a FixedHeader, set nextMessageLength
 *   to the total length of the message.  (3) After reading nextMessageLength bytes, return the outputBuffer
 *   and reset nextMessageLength to 0.
 *
 * @param input is the PARCEventBuffer to read
 * @param stream is the related stream state for the input
 * @return true if there's more to read after this message.
 */
static MetisMessage *
_single_read(PARCEventBuffer *input, _MetisStreamState *stream)
{
    size_t bytesAvailable = parcEventBuffer_GetLength(input);

    assertTrue(bytesAvailable >= metisTlv_FixedHeaderLength(), "Called with too short an input: %zu", bytesAvailable);

    if (metisLogger_IsLoggable(stream->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug)) {
        metisLogger_Log(stream->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug, __func__,
                        "connid %u read %zu bytes",
                        stream->id, bytesAvailable);
    }

    if (stream->nextMessageLength == 0) {
        _startNewMessage(stream, input, bytesAvailable);
    }

    // This is not an ELSE statement.  We can both start a new message then
    // check if there's enough bytes to read the whole thing.

    if (bytesAvailable >= stream->nextMessageLength) {
        MetisMessage *message = _readMessage(stream, metisForwarder_GetTicks(stream->metis), input);

        if (metisLogger_IsLoggable(stream->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug)) {
            metisLogger_Log(stream->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug, __func__,
                            "connid %u msg_length %zu read_length %zu, resetting parser",
                            stream->id,
                            stream->nextMessageLength,
                            bytesAvailable);
        }

        // now reset message length for next packet
        stream->nextMessageLength = 0;

        return message;
    }

    return NULL;
}
예제 #4
0
static void
metisConfiguration_SendResponse(MetisConfiguration *config, CCNxControl *response, unsigned egressId)
{
    PARCBuffer *responseBuffer = metisTlv_EncodeControlPlaneInformation(response);
    MetisMessage *tlvEncodedResponse = metisMessage_CreateFromParcBuffer(responseBuffer, 0, metisForwarder_GetTicks(config->metis), metisForwarder_GetLogger(config->metis));

    parcBuffer_Release(&responseBuffer);

    MetisConnectionTable *connectionTable = metisForwarder_GetConnectionTable(config->metis);
    const MetisConnection *conn = metisConnectionTable_FindById(connectionTable, egressId);
    assertNotNull(conn, "Got null connection for control message we just received");

    metisConnection_Send(conn, tlvEncodedResponse);
    metisMessage_Release(&tlvEncodedResponse);
}