Beispiel #1
0
LONGBOW_TEST_CASE(Global, parcBitVector_SetVector)
{
    PARCBitVector *parcBitVector = parcBitVector_Create();
    assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer");
    PARCBitVector *setVector = parcBitVector_Create();
    parcBitVector_Set(parcBitVector, 1);
    assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 1, "parcBitVector_Set failed");

    parcBitVector_Set(setVector, 20);
    parcBitVector_SetVector(parcBitVector, setVector);
    assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 2, "parcBitVector_SetVector failed");
    assertTrue(parcBitVector_NextBitSet(parcBitVector, 0) == 1, "parcBitVector_Set failed to set bit 1");
    assertTrue(parcBitVector_NextBitSet(parcBitVector, 2) == 20, "parcBitVector_SetVector failed to set bit 20");

    parcBitVector_Set(setVector, 10);
    parcBitVector_SetVector(parcBitVector, setVector);
    assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 3, "parcBitVector_SetVector failed");
    parcBitVector_Release(&parcBitVector);
    parcBitVector_Release(&setVector);
}
PARCBitVector *
athenaTransportLinkAdapter_Send(AthenaTransportLinkAdapter *athenaTransportLinkAdapter,
                                CCNxMetaMessage *ccnxMetaMessage,
                                PARCBitVector *linkOutputVector)
{
    PARCBitVector *resultVector = parcBitVector_Create();
    int nextLinkToWrite = 0;

    if (athenaTransportLinkAdapter->instanceList == NULL) {
        return resultVector;
    }

    while ((nextLinkToWrite = parcBitVector_NextBitSet(linkOutputVector, nextLinkToWrite)) >= 0) {
        athenaTransportLinkAdapter->stats.messageSend_Attempted++;
        if (nextLinkToWrite >= parcArrayList_Size(athenaTransportLinkAdapter->instanceList)) {
            athenaTransportLinkAdapter->stats.messageSend_LinkDoesNotExist++;
            nextLinkToWrite++;
            continue;
        }
        AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, nextLinkToWrite);
        if (athenaTransportLink == NULL) {
            athenaTransportLinkAdapter->stats.messageSend_LinkDoesNotExist++;
            nextLinkToWrite++;
            continue;
        }
        if (!(athenaTransportLink_GetEvent(athenaTransportLink) & AthenaTransportLinkEvent_Send)) {
            athenaTransportLinkAdapter->stats.messageSend_LinkNotAcceptingSendRequests++;
            nextLinkToWrite++;
            continue;
        }
        // If we're sending an interest to a non-local link,
        // check that it has a sufficient hoplimit.
        if (ccnxMetaMessage_IsInterest(ccnxMetaMessage)) {
            if (athenaTransportLink_IsNotLocal(athenaTransportLink)) {
                if (ccnxInterest_GetHopLimit(ccnxMetaMessage) == 0) {
                    athenaTransportLinkAdapter->stats.messageSend_HopLimitExceeded++;
                    nextLinkToWrite++;
                    continue;
                }
            }
        }
        int result = athenaTransportLink_Send(athenaTransportLink, ccnxMetaMessage);
        if (result == 0) {
            athenaTransportLinkAdapter->stats.messageSent++;
            parcBitVector_Set(resultVector, nextLinkToWrite);
        } else {
            athenaTransportLinkAdapter->stats.messageSend_LinkSendFailed++;
        }
        nextLinkToWrite++;
    }

    return resultVector;
}
Beispiel #3
0
LONGBOW_TEST_CASE(Global, parcBitVector_NextBitSet)
{
    PARCBitVector *parcBitVector = parcBitVector_Create();
    assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer");
    assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Create created a non-empty vector");

    int nextBit = parcBitVector_NextBitSet(parcBitVector, 0);
    assertTrue(nextBit == -1, "parcBitVector_NextBitSet should have failed (%d)", nextBit);

    parcBitVector_Set(parcBitVector, 10);
    nextBit = parcBitVector_NextBitSet(parcBitVector, 0);
    assertTrue(nextBit == 10, "parcBitVector_NextBitSet failed (%d)", nextBit);

    nextBit = parcBitVector_NextBitSet(parcBitVector, 20);
    assertTrue(nextBit == -1, "parcBitVector_NextBitSet read past end of vector (%d)", nextBit);

    nextBit = parcBitVector_NextBitSet(parcBitVector, 10);
    assertTrue(nextBit == 10, "parcBitVector_NextBitSet failed (%d)", nextBit);

    nextBit = parcBitVector_NextBitSet(parcBitVector, 11);
    assertTrue(nextBit == -1, "parcBitVector_NextBitSet should have failed (%d)", nextBit);

    parcBitVector_Set(parcBitVector, 20);
    nextBit = parcBitVector_NextBitSet(parcBitVector, 11);
    assertTrue(nextBit == 20, "parcBitVector_NextBitSet failed (%d)", nextBit);
    parcBitVector_Release(&parcBitVector);
}
Beispiel #4
0
LONGBOW_TEST_CASE(Global, parcBitVector_Copy)
{
    PARCBitVector *parcBitVector = parcBitVector_Create();
    assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer");

    parcBitVector_Set(parcBitVector, 10);
    PARCBitVector *copy = parcBitVector_Copy(parcBitVector);
    assertTrue(parcBitVector_NumberOfBitsSet(copy) == 1, "parcBitVector_Copy failed to copy set bit");
    assertTrue(parcBitVector_NextBitSet(copy, 0) == 10, "parcBitVector_Copy failed to copy correct bit");

    parcBitVector_Release(&copy);
    parcBitVector_Release(&parcBitVector);
}
PARCBitVector *
athenaTransportLinkAdapter_Close(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, PARCBitVector *linkVector)
{
    PARCBitVector *resultVector = parcBitVector_Create();
    int nextLinkToClose = 0;
    while ((nextLinkToClose = parcBitVector_NextBitSet(linkVector, nextLinkToClose)) >= 0) {
        AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, nextLinkToClose);
        if (athenaTransportLink) {
            athenaTransportLink_Close(athenaTransportLink);
            parcBitVector_Set(resultVector, nextLinkToClose);
            nextLinkToClose++;
        }
    }
    return resultVector;
}
Beispiel #6
0
static CCNxMetaMessage *
_FIB_Command(Athena *athena, CCNxInterest *interest, PARCBitVector *ingress)
{
    CCNxMetaMessage *responseMessage;
    responseMessage = athenaFIB_ProcessMessage(athena->athenaFIB, interest);
    if (responseMessage) {
        return responseMessage;
    }

    CCNxName *ccnxName = ccnxInterest_GetName(interest);
    if (ccnxName_GetSegmentCount(ccnxName) > AthenaCommandSegment) {
        CCNxNameSegment *nameSegment = ccnxName_GetSegment(ccnxName, AthenaCommandSegment);
        char *command = ccnxNameSegment_ToString(nameSegment);

        if ((strcasecmp(command, AthenaCommand_Add) == 0) || (strcasecmp(command, AthenaCommand_Remove) == 0)) {
            char *arguments = _get_arguments(interest);

            if (arguments == NULL) {
                responseMessage = _create_response(athena, ccnxName, "No link or prefix arguments given to %s route command", command);
                parcMemory_Deallocate(&command);
                return responseMessage;
            }

            char linkName[MAXPATHLEN];
            char prefix[MAXPATHLEN];
            PARCBitVector *linkVector;

            // {Add,Remove} Route arguments "<prefix> [<linkName>]", if linkName not specified, use the incoming link id ([de-]registration)
            int numberOfArguments = sscanf(arguments, "%s %s", prefix, linkName);
            if (numberOfArguments == 2) {
                int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, linkName);
                if (linkId == -1) {
                    responseMessage = _create_response(athena, ccnxName, "Unknown linkName %s", linkName);
                    parcMemory_Deallocate(&command);
                    parcMemory_Deallocate(&arguments);
                    return responseMessage;
                }
                linkVector = parcBitVector_Create();
                parcBitVector_Set(linkVector, linkId);
            } else if (numberOfArguments == 1) { // use ingress link
                linkVector = parcBitVector_Acquire(ingress);
            } else {
                responseMessage = _create_response(athena, ccnxName, "No prefix specified or too many arguments");
                parcMemory_Deallocate(&command);
                parcMemory_Deallocate(&arguments);
                return responseMessage;
            }

            CCNxName *prefixName = ccnxName_CreateFromCString(prefix);
            if (prefixName == NULL) {
                responseMessage = _create_response(athena, ccnxName, "Unable to parse prefix %s", prefix);
                parcMemory_Deallocate(&command);
                parcMemory_Deallocate(&arguments);
                parcBitVector_Release(&linkVector);
                return responseMessage;
            }

            int result = false;
            if (strcasecmp(command, AthenaCommand_Add) == 0) {
                result = athenaFIB_AddRoute(athena->athenaFIB, prefixName, linkVector);
            } else if (strcasecmp(command, AthenaCommand_Remove) == 0) {
                result = athenaFIB_DeleteRoute(athena->athenaFIB, prefixName, linkVector);
            }

            if (result == true) {
                char *routePrefix = ccnxName_ToString(prefixName);
                const char *linkIdName = athenaTransportLinkAdapter_LinkIdToName(athena->athenaTransportLinkAdapter, parcBitVector_NextBitSet(linkVector, 0));
                responseMessage = _create_response(athena, ccnxName, "%s route %s -> %s", command, routePrefix, linkIdName);
                athenaInterestControl_LogConfigurationChange(athena, ccnxName, "%s %s", routePrefix, linkIdName);
                parcMemory_Deallocate(&routePrefix);
            } else {
                responseMessage = _create_response(athena, ccnxName, "%s failed", command);
            }
            parcBitVector_Release(&linkVector);
            ccnxName_Release(&prefixName);

            parcMemory_Deallocate(&arguments);
        } else if (strcasecmp(command, AthenaCommand_List) == 0) {
            // Need to create the response here because as the FIB doesn't know the linkName
            parcLog_Debug(athena->log, "FIB List command invoked");
            PARCList *fibEntries = athenaFIB_CreateEntryList(athena->athenaFIB);
            responseMessage = _create_FIBList_response(athena, ccnxName, fibEntries);
            parcList_Release(&fibEntries);
        } else {
            responseMessage = _create_response(athena, ccnxName, "Unknown command: %s", command);
        }

        parcMemory_Deallocate(&command);
    }
    return responseMessage;
}
Beispiel #7
0
static void
_processInterest(Athena *athena, CCNxInterest *interest, PARCBitVector *ingressVector)
{
    uint8_t hoplimit;

    //
    // *   (0) Hoplimit check, exclusively on interest messages
    //
    int linkId = parcBitVector_NextBitSet(ingressVector, 0);
    if (athenaTransportLinkAdapter_IsNotLocal(athena->athenaTransportLinkAdapter, linkId)) {
        hoplimit = ccnxInterest_GetHopLimit(interest);
        if (hoplimit == 0) {
            // We should never receive a message with a hoplimit of 0 from a non-local source.
            parcLog_Error(athena->log,
                          "Received a message with a hoplimit of zero from a non-local source (%s).",
                          athenaTransportLinkAdapter_LinkIdToName(athena->athenaTransportLinkAdapter, linkId));
            return;
        }
        ccnxInterest_SetHopLimit(interest, hoplimit - 1);
    }

    //
    // *   (1) if the interest is in the ContentStore, reply and return,
    //     assuming that other PIT entries were satisified when the content arrived.
    //
    CCNxMetaMessage *content = athenaContentStore_GetMatch(athena->athenaContentStore, interest);
    if (content) {
        const char *ingressVectorString = parcBitVector_ToString(ingressVector);
        parcLog_Debug(athena->log, "Forwarding content from store to %s", ingressVectorString);
        parcMemory_Deallocate(&ingressVectorString);
        PARCBitVector *result = athenaTransportLinkAdapter_Send(athena->athenaTransportLinkAdapter, content, ingressVector);
        if (result) { // failed channels - client will resend interest unless we wish to optimize things here
            parcBitVector_Release(&result);
        }
        return;
    }

    //
    // *   (2) add it to the PIT, if it was aggregated or there was an error we're done, otherwise we
    //         forward the interest.  The expectedReturnVector is populated with information we get from
    //         the FIB and used to verify content objects ingress ports when they arrive.
    //
    PARCBitVector *expectedReturnVector;
    AthenaPITResolution result;
    if ((result = athenaPIT_AddInterest(athena->athenaPIT, interest, ingressVector, &expectedReturnVector)) != AthenaPITResolution_Forward) {
        if (result == AthenaPITResolution_Error) {
            parcLog_Error(athena->log, "PIT resolution error");
        }
        return;
    }

    // Divert interests destined to the forwarder, we assume these are control messages
    CCNxName *ccnxName = ccnxInterest_GetName(interest);
    if (ccnxName_StartsWith(ccnxName, athena->athenaName) == true) {
        _processInterestControl(athena, interest, ingressVector);
        return;
    }

    //
    // *   (3) if it's in the FIB, forward, then update the PIT expectedReturnVector so we can verify
    //         when the returned object arrives that it came from an interface it was expected from.
    //         Interest messages with a hoplimit of 0 will never be sent out by the link adapter to a
    //         non-local interface so we need not check that here.
    //
    ccnxName = ccnxInterest_GetName(interest);
    PARCBitVector *egressVector = athenaFIB_Lookup(athena->athenaFIB, ccnxName);

    if (egressVector != NULL) {
        // Remove the link the interest came from if it was included in the FIB entry
        parcBitVector_ClearVector(egressVector, ingressVector);
        // If no links remain, send a no route interest return message
        if (parcBitVector_NumberOfBitsSet(egressVector) == 0) {
            CCNxInterestReturn *interestReturn = ccnxInterestReturn_Create(interest, CCNxInterestReturn_ReturnCode_NoRoute);
            PARCBitVector *result = athenaTransportLinkAdapter_Send(athena->athenaTransportLinkAdapter, interestReturn, ingressVector);
            parcBitVector_Release(&result);
            ccnxInterestReturn_Release(&interestReturn);
        } else {
            parcBitVector_SetVector(expectedReturnVector, egressVector);
            PARCBitVector *result = athenaTransportLinkAdapter_Send(athena->athenaTransportLinkAdapter, interest, egressVector);
            if (result) { // remove failed channels - client will resend interest unless we wish to optimize here
                parcBitVector_ClearVector(expectedReturnVector, result);
                parcBitVector_Release(&result);
            }
        }
    } else {
        // No FIB entry found, return a NoRoute interest return and remove the entry from the PIT.
        CCNxInterestReturn *interestReturn = ccnxInterestReturn_Create(interest, CCNxInterestReturn_ReturnCode_NoRoute);
        PARCBitVector *result = athenaTransportLinkAdapter_Send(athena->athenaTransportLinkAdapter, interestReturn, ingressVector);
        parcBitVector_Release(&result);
        ccnxInterestReturn_Release(&interestReturn);
        const char *name = ccnxName_ToString(ccnxName);
        if (athenaPIT_RemoveInterest(athena->athenaPIT, interest, ingressVector) != true) {
            parcLog_Error(athena->log, "Unable to remove interest (%s) from the PIT.", name);
        }
        parcLog_Debug(athena->log, "Name (%s) not found in FIB and no default route. Message dropped.", name);
        parcMemory_Deallocate(&name);
    }
}