// 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; }
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; }
/** * @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; }
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); }