Beispiel #1
0
static CCNxMetaMessage *
_ContentStore_Command(Athena *athena, CCNxInterest *interest)
{
    CCNxMetaMessage *responseMessage;
    responseMessage = athenaContentStore_ProcessMessage(athena->athenaContentStore, 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);

        //char *arguments = _get_arguments(interest);

        //responseMessage = _create_response(athena, ccnxName, ...

        //parcMemory_Deallocate(&command);
        //if (arguments) {
        //    parcMemory_Deallocate(&arguments);
        //}

        parcMemory_Deallocate(&command);
    }
    return responseMessage;
}
LONGBOW_TEST_CASE(Global, ccnxInterest_SetGetPayload)
{
    CCNxName *name = ccnxName_CreateFromURI("lci:/name");
    CCNxInterest *interest = ccnxInterest_CreateSimple(name);
    CCNxName *origNameCopy = ccnxName_Copy(name);

    CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);

    if (impl->getPayload) {
        assertNull(ccnxInterest_GetPayload(interest), "Expected a NULL payload");
    }

    if (impl->getPayload && impl->setPayload) {
        PARCBuffer *payload = parcBuffer_WrapCString("impls have pimples");
        ccnxInterest_SetPayload(interest, payload);

        PARCBuffer *payloadOut = ccnxInterest_GetPayload(interest);

        assertTrue(parcBuffer_Equals(payload, payloadOut), "Expected an equal buffer");

        CCNxName *nameAfterPayload = ccnxInterest_GetName(interest);
        assertTrue(ccnxName_Equals(nameAfterPayload, origNameCopy), "Expected an unmodified name");

        parcBuffer_Release(&payload);
    }
    ccnxName_Release(&name);
    ccnxName_Release(&origNameCopy);
    ccnxInterest_Release(&interest);
}
LONGBOW_TEST_CASE(Global, ccnxInterest_SetPayloadAndId)
{
    CCNxName *name = ccnxName_CreateFromURI("lci:/name");
    CCNxInterest *interest = ccnxInterest_CreateSimple(name);

    CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);

    if (impl->getPayload) {
        assertNull(ccnxInterest_GetPayload(interest), "Expected a NULL payload");
    }

    if (impl->getPayload && impl->setPayload) {
        PARCBuffer *payload = parcBuffer_WrapCString("impls have pimples");

        ccnxInterest_SetPayloadAndId(interest, payload);

        PARCBuffer *payloadOut = ccnxInterest_GetPayload(interest);

        assertTrue(parcBuffer_Equals(payload, payloadOut), "Expected an equal buffer");

        CCNxName *nameAfterPayload = ccnxInterest_GetName(interest);
        CCNxNameSegment *segment = ccnxName_GetSegment(nameAfterPayload, ccnxName_GetSegmentCount(nameAfterPayload) - 1);

        assertTrue(ccnxNameSegment_GetType(segment) == CCNxNameLabelType_PAYLOADID, "Expected to find a payload ID appended to the name");

        parcBuffer_Release(&payload);
    }
    ccnxName_Release(&name);
    ccnxInterest_Release(&interest);
}
Beispiel #4
0
/**
 * Given a CCnxInterest that matched our domain prefix, see what the embedded command is and
 * create a corresponding CCNxContentObject as a response. The resulting CCNxContentObject
 * must eventually be released by calling ccnxContentObject_Release().
 *
 * @param [in] interest A CCNxInterest that matched the specified domain prefix.
 * @param [in] domainPrefix A CCNxName containing the domain prefix.
 * @param [in] directoryPath A string containing the path to the directory being served.
 *
 * @return A newly creatd CCNxContentObject contaning a response to the specified Interest,
 *         or NULL if the Interest couldn't be answered.
 */
static CCNxContentObject *
_createInterestResponse(const CCNxInterest *interest, const CCNxName *domainPrefix, const char *directoryPath)
{
    CCNxName *interestName = ccnxInterest_GetName(interest);

    char *command = tutorialCommon_CreateCommandStringFromName(interestName, domainPrefix);

    uint64_t requestedChunkNumber = tutorialCommon_GetChunkNumberFromName(interestName);

    char *interestNameString = ccnxName_ToString(interestName);
    printf("tutorialServer: received Interest for chunk %d of %s, command = %s\n",
           (int) requestedChunkNumber, interestNameString, command);
    parcMemory_Deallocate((void **) &interestNameString);

    CCNxContentObject *result = NULL;
    if (strncasecmp(command, tutorialCommon_CommandList, strlen(command)) == 0) {
        // This was a 'list' command. We should return the requested chunk of the directory listing.
        result = _createListResponse(interestName, directoryPath, requestedChunkNumber);
    } else if (strncasecmp(command, tutorialCommon_CommandFetch, strlen(command)) == 0) {
        // This was a 'fetch' command. We should return the requested chunk of the file specified.
        char *fileName = tutorialCommon_CreateFileNameFromName(interestName);
        result = _createFetchResponse(interestName, directoryPath, fileName, requestedChunkNumber);
        parcMemory_Deallocate((void **) &fileName);
    }

    parcMemory_Deallocate((void **) &command);

    return result;
}
Beispiel #5
0
void
athena_ProcessMessage(Athena *athena, CCNxMetaMessage *ccnxMessage, PARCBitVector *ingressVector)
{
    if (ccnxMetaMessage_IsInterest(ccnxMessage)) {
        const char *name = ccnxName_ToString(ccnxInterest_GetName(ccnxMessage));
        parcLog_Debug(athena->log, "Processing Interest Message: %s", name);
        parcMemory_Deallocate(&name);

        CCNxInterest *interest = ccnxMetaMessage_GetInterest(ccnxMessage);
        _processInterest(athena, interest, ingressVector);
        athena->stats.numProcessedInterests++;
    } else if (ccnxMetaMessage_IsContentObject(ccnxMessage)) {
        const char *name = ccnxName_ToString(ccnxContentObject_GetName(ccnxMessage));
        parcLog_Debug(athena->log, "Processing Content Object Message: %s", name);
        parcMemory_Deallocate(&name);

        CCNxContentObject *contentObject = ccnxMetaMessage_GetContentObject(ccnxMessage);
        _processContentObject(athena, contentObject, ingressVector);
        athena->stats.numProcessedContentObjects++;
    } else if (ccnxMetaMessage_IsControl(ccnxMessage)) {
        parcLog_Debug(athena->log, "Processing Control Message");

        CCNxControl *control = ccnxMetaMessage_GetControl(ccnxMessage);
        _processControl(athena, control, ingressVector);
        athena->stats.numProcessedControlMessages++;
    } else if (ccnxMetaMessage_IsInterestReturn(ccnxMessage)) {
        parcLog_Debug(athena->log, "Processing Interest Return Message");

        CCNxInterestReturn *interestReturn = ccnxMetaMessage_GetInterestReturn(ccnxMessage);
        _processInterestReturn(athena, interestReturn, ingressVector);
        athena->stats.numProcessedInterestReturns++;
    } else {
        trapUnexpectedState("Invalid CCNxMetaMessage type");
    }
}
Beispiel #6
0
static CCNxMetaMessage *
_PIT_Command(Athena *athena, CCNxInterest *interest)
{
    CCNxMetaMessage *responseMessage;
    responseMessage = athenaPIT_ProcessMessage(athena->athenaPIT, 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_List) == 0) {
            parcLog_Debug(athena->log, "PIT List command invoked");
            PARCList *pitEntries = athenaPIT_CreateEntryList(athena->athenaPIT);
            printf("\n");
            for (size_t i = 0; i < parcList_Size(pitEntries); ++i) {
                PARCBuffer *strbuf = parcList_GetAtIndex(pitEntries, i);
                char *toprint = parcBuffer_ToString(strbuf);
                parcLog_Info(athena->log, "%s\n", toprint);
                parcMemory_Deallocate(&toprint);
            }
            parcList_Release(&pitEntries);
            responseMessage = _create_response(athena, ccnxName, "PIT listed on forwarder output log.");
        } else {
            responseMessage = _create_response(athena, ccnxName, "Unknown command: %s", command);
        }

        parcMemory_Deallocate(&command);
    }
    return responseMessage;
}
Beispiel #7
0
static CCNxMetaMessage *
_athenaLRUContentStore_ProcessMessage(AthenaContentStoreImplementation *store, const CCNxMetaMessage *message)
{
    CCNxMetaMessage *result = NULL;
    AthenaLRUContentStore *impl = (AthenaLRUContentStore *) store;

    if (ccnxMetaMessage_IsInterest(message)) {
        CCNxInterest *interest = ccnxMetaMessage_GetInterest(message);
        CCNxName *queryName = ccnxInterest_GetName(interest);

        uint64_t chunkNumber = 0;
        bool hasChunkNumber = false;
        _getChunkNumberFromName(queryName, &chunkNumber, &hasChunkNumber);
        assertFalse(hasChunkNumber, "LRUContentStore queries don't yet support more than 1 chunk.");

        PARCBuffer *responsePayload = NULL;

        // Find the arguments to our query.
        size_t argSegmentIndex = 0;
        if (_getSegmentIndexOfQueryArgs(queryName, AthenaModule_ContentStore, &argSegmentIndex)) {
            CCNxNameSegment *queryTypeSegment = ccnxName_GetSegment(queryName, argSegmentIndex);
            char *queryTypeString = ccnxNameSegment_ToString(queryTypeSegment);  // e.g. "stat"

            char *statString = "stat";
            if (strncasecmp(queryTypeString, statString, strlen(statString)) == 0) {
                responsePayload = _processStatQuery(impl, queryName, argSegmentIndex + 1, chunkNumber);
            }
            parcMemory_Deallocate(&queryTypeString);
        }

        if (responsePayload != NULL) {
            CCNxContentObject *contentObjectResponse = ccnxContentObject_CreateWithNameAndPayload(
                ccnxInterest_GetName(interest), responsePayload);

            result = ccnxMetaMessage_CreateFromContentObject(contentObjectResponse);
            ccnxContentObject_SetExpiryTime(contentObjectResponse,
                                            parcClock_GetTime(impl->wallClock) +
                                            100); // this response is good for 100 millis

            ccnxContentObject_Release(&contentObjectResponse);
            parcBuffer_Release(&responsePayload);
        }
    }

    return result;  // could be NULL
}
Beispiel #8
0
static CCNxContentObject *
//_athenaLRUContentStore_GetMatch(AthenaContentStoreImplementation *store, const CCNxName *name, const PARCBuffer *keyIdRestriction,
//                                const PARCBuffer *contentObjectHash)
_athenaLRUContentStore_GetMatch(AthenaContentStoreImplementation *store, const CCNxInterest *interest)
{
    CCNxContentObject *result = NULL;
    AthenaLRUContentStore *impl = (AthenaLRUContentStore *) store;
    _AthenaLRUContentStoreEntry *entry = NULL;

    CCNxName *name = ccnxInterest_GetName(interest);
    PARCBuffer *contentObjectHashRestriction = ccnxInterest_GetContentObjectHashRestriction(interest);
    PARCBuffer *keyIdRestriction = ccnxInterest_GetKeyIdRestriction(interest);

    if (contentObjectHashRestriction != NULL) {
        PARCObject *nameAndHashKey = _createHashableKey(name, NULL, contentObjectHashRestriction);
        entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByNameAndObjectHash, nameAndHashKey);
        parcObject_Release((PARCObject **) &nameAndHashKey);
    }

    if ((entry == NULL) && (keyIdRestriction != NULL)) {
        PARCObject *nameAndKeyIdKey = _createHashableKey(name, keyIdRestriction, NULL);
        entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByNameAndKeyId, nameAndKeyIdKey);
        parcObject_Release((PARCObject **) &nameAndKeyIdKey);
    }

    if (entry == NULL) {
        PARCObject *nameKey = _createHashableKey(name, NULL, NULL);
        entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByName, nameKey);
        parcObject_Release((PARCObject **) &nameKey);
    }

    // Matching is done. Now check for validity, if necessary.

    if (entry != NULL) {
        // We found matching content. Now make sure it's not expired before returning it. If it is expired,
        // remove it from the store and don't return anything.
        if (entry->hasExpiryTime && (entry->expiryTime < parcClock_GetTime(impl->wallClock))) {
            _athenaLRUContentStore_PurgeContentStoreEntry(impl, entry);
            entry = NULL;
        }

        // XXX: TODO: Check that the KeyId, if any, was verified.
    }

    // At this point, the cached content is considered valid for responding with. Return it.
    if (entry != NULL) {
        result = entry->contentObject;

        // Update LRU so that the matched entry is at the top of the list.
        _moveContentStoreEntryToLRUHead(impl, entry);

        impl->stats.numMatchHits++;
    } else {
        impl->stats.numMatchMisses++;
    }

    return result;
}
int
reader_writer(CCNxPortalFactory *factory, const char *uri)
{

    CCNxPortal *portal = ccnxPortalFactory_GetInstance(factory, ccnxPortalTypeDatagram, ccnxPortalProtocol_TLV, &ccnxPortalAttributes_Blocking);

    CCNxName *prefix = ccnxName_CreateFromURI(uri);
    CCNxName *bye = ccnxName_CreateFromURI("lci:/Hello/Goodbye%21");
    CCNxName *contentname = ccnxName_CreateFromURI("lci:/Hello/World");

    if (ccnxPortal_Listen(portal, prefix, 365 * 86400, CCNxStackTimeout_Never)) {
        CCNxMetaMessage *msg;

        while ((msg = ccnxPortal_Receive(portal, CCNxStackTimeout_Never)) != NULL) {

            if (ccnxMetaMessage_IsInterest(msg)) {
                CCNxInterest *interest = ccnxMetaMessage_GetInterest(msg);

                CCNxName *interestName = ccnxInterest_GetName(interest);

                if (ccnxName_Equals(interestName, contentname)) {
                    const PARCKeyId *publisherKeyId = ccnxPortal_GetKeyId(portal);

                    char buffer[128];
                    time_t theTime = time(0);
                    sprintf(buffer, "Hello World. The time is %s", ctime(&theTime));

                    PARCBuffer *payload = parcBuffer_CreateFromArray(buffer, 128);
                    parcBuffer_Flip(payload);

                    PARCBuffer *b = parcBuffer_Acquire(payload);
                    CCNxContentObject *uob = ccnxContentObject_CreateWithDataPayload(contentname, b);

                    // missing NULL check, case 1024

                    CCNxMetaMessage *message = ccnxMetaMessage_CreateFromContentObject(uob);
                    if (ccnxPortal_Send(portal, message, CCNxTransportStackTimeCCNxStackTimeout_Neverout_Never) == false) {
                        fprintf(stderr, "ccnx_write failed\n");
                    }
                    // ccnxMessage_Release(message);
                } else if (ccnxName_Equals(interestName, bye)) {
                    break;
                }
            } else {
                ccnxMetaMessage_Display(msg, 0);
            }
            ccnxMetaMessage_Release(&msg);
        }
    }

    ccnxName_Release(&prefix);
    ccnxName_Release(&bye);
    ccnxName_Release(&contentname);

    ccnxPortal_Release(&portal);

    return 0;
}
Beispiel #10
0
static CCNxMetaMessage *
_TransportLinkAdapter_Command(Athena *athena, CCNxInterest *interest)
{
    CCNxMetaMessage *responseMessage;
    responseMessage = athenaTransportLinkAdapter_ProcessMessage(athena->athenaTransportLinkAdapter, 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);

        char *arguments = _get_arguments(interest);
        if (arguments == NULL) {
            responseMessage = _create_response(athena, ccnxName, "No link arguments given to %s command", command);
            parcMemory_Deallocate(&command);
            return responseMessage;
        }

        if (strcasecmp(command, AthenaCommand_Add) == 0) {
            if (arguments) {
                PARCURI *connectionURI = parcURI_Parse(arguments);
                if (connectionURI == NULL) {
                    responseMessage = _create_response(athena, ccnxName, "Could not parse URI:  %s", arguments);
                    return responseMessage;
                }
                const char *linkName = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI);
                parcURI_Release(&connectionURI);
                if (linkName) {
                    responseMessage = _create_response(athena, ccnxName, "%s", linkName);
                    athenaInterestControl_LogConfigurationChange(athena, ccnxName, "%s", arguments);
                } else {
                    responseMessage = _create_response(athena, ccnxName, "New %s link failed: %s", arguments, strerror(errno));
                }
            }
        } else if (strcasecmp(command, AthenaCommand_Remove) == 0) {
            if (arguments) {
                int result = athenaTransportLinkAdapter_CloseByName(athena->athenaTransportLinkAdapter, arguments);
                if (result) {
                    responseMessage = _create_response(athena, ccnxName, "removal of %s failed", arguments);
                } else {
                    responseMessage = _create_response(athena, ccnxName, "%s removed", arguments);
                    athenaInterestControl_LogConfigurationChange(athena, ccnxName, "%s", arguments);
                }
            }
        } else {
            responseMessage = _create_response(athena, ccnxName, "Unknown TransportLinkAdapter command %s", command);
        }

        parcMemory_Deallocate(&command);
        parcMemory_Deallocate(&arguments);
    }
    return responseMessage;
}
LONGBOW_TEST_CASE(Global, ccnxInterest_GetName)
{
    CCNxName *name = ccnxName_CreateFromURI("lci:/name");
    CCNxInterest *interest = ccnxInterest_CreateSimple(name);

    CCNxName *actual = ccnxInterest_GetName(interest);
    assertTrue(ccnxName_Equals(name, actual), "Expected the same name.");

    ccnxName_Release(&name);
    ccnxInterest_Release(&interest);
}
int
ccnServe(const PARCIdentity *identity, const CCNxName *listenName, const char *commandString)
{
    parcSecurity_Init();

    CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);

    CCNxPortal *portal = ccnxPortalFactory_CreatePortal(factory, ccnxPortalRTA_Message);
    assertNotNull(portal, "Expected a non-null CCNxPortal pointer.");

    if (ccnxPortal_Listen(portal, listenName, 365 * 86400, CCNxStackTimeout_Never)) {
        while (true) {
            CCNxMetaMessage *request = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);

            if (request == NULL) {
                break;
            }

            CCNxInterest *interest = ccnxMetaMessage_GetInterest(request);

            if (interest != NULL) {
                CCNxName *interestName = ccnxInterest_GetName(interest);

                PARCBuffer *payload = makePayload(interestName, commandString);

                CCNxContentObject *contentObject = ccnxContentObject_CreateWithDataPayload(interestName, payload);

                CCNxMetaMessage *message = ccnxMetaMessage_CreateFromContentObject(contentObject);
                if (ccnxPortal_Send(portal, message, CCNxStackTimeout_Never) == false) {
                    fprintf(stderr, "ccnxPortal_Write failed: %d\n", ccnxPortal_GetError(portal));
                }
                {
                    char *name = ccnxName_ToString(interestName);
                    time_t theTime = time(0);
                    char *time = ctime(&theTime);
                    printf("%24.24s  %s\n", time, name);
                    parcMemory_Deallocate((void **) &name);
                }

                parcBuffer_Release(&payload);
            }
            ccnxMetaMessage_Release(&request);
        }
    }

    ccnxPortal_Release(&portal);

    ccnxPortalFactory_Release(&factory);

    parcSecurity_Fini();

    return 0;
}
Beispiel #13
0
static CCNxMetaMessage *
_Control_Command(Athena *athena, CCNxInterest *interest)
{
    CCNxMetaMessage *responseMessage;
    responseMessage = athenaControl_ProcessMessage(athena, interest);
    if (responseMessage) {
        return responseMessage;
    }

    CCNxName *ccnxName = ccnxInterest_GetName(interest);
    if (ccnxName_GetSegmentCount(ccnxName) <= AthenaCommandSegment) {
        responseMessage = _create_response(athena, ccnxName, "No command specified");
        return responseMessage;
    }

    CCNxNameSegment *nameSegment = ccnxName_GetSegment(ccnxName, AthenaCommandSegment);
    char *command = ccnxNameSegment_ToString(nameSegment);

    // Set <level> <debug,info>
    if (strncasecmp(command, AthenaCommand_Set, strlen(AthenaCommand_Set)) == 0) {
        responseMessage = _Control_Command_Set(athena, ccnxName, command);
        parcMemory_Deallocate(&command);
        return responseMessage;
    }

    // Quit
    if (strncasecmp(command, AthenaCommand_Quit, strlen(AthenaCommand_Quit)) == 0) {
        responseMessage = _Control_Command_Quit(athena, ccnxName, command);
        parcMemory_Deallocate(&command);
        return responseMessage;
    }

    // Stats
    if (strncasecmp(command, AthenaCommand_Stats, strlen(AthenaCommand_Stats)) == 0) {
        responseMessage = _Control_Command_Stats(athena, ccnxName, command);
        parcMemory_Deallocate(&command);
        return responseMessage;
    }

    // Spawn
    if (strncasecmp(command, AthenaCommand_Run, strlen(AthenaCommand_Run)) == 0) {
        const char *connectionSpecification = _get_arguments(interest);
        responseMessage = _Control_Command_Spawn(athena, ccnxName, command, connectionSpecification);
        parcMemory_Deallocate(&connectionSpecification);
        parcMemory_Deallocate(&command);
        return responseMessage;
    }

    responseMessage = _create_response(athena, ccnxName, "Unknown command \"%s\"", command);
    parcMemory_Deallocate(&command);
    return responseMessage;
}
CCNxContentObject *
athenaTransportLinkAdapter_ProcessMessage(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, const CCNxInterest *interest)
{
    CCNxMetaMessage *responseMessage = NULL;

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

        if (strcmp(command, AthenaCommand_List) == 0) {
            responseMessage = _create_linkList_response(athenaTransportLinkAdapter, ccnxName);
        }
        parcMemory_Deallocate(&command);
    }
    return responseMessage;
}
Beispiel #15
0
int
athenaInterestControl(Athena *athena, CCNxInterest *interest, PARCBitVector *ingressVector)
{
    CCNxMetaMessage *responseMessage = NULL;
    CCNxName *ccnxName = ccnxInterest_GetName(interest);

    CCNxName *ccnxComponentName = ccnxName_CreateFromCString(CCNxNameAthena_Control);
    if (ccnxName_StartsWith(ccnxName, ccnxComponentName) == true) {
        responseMessage = _Control_Command(athena, interest);
    }
    ccnxName_Release(&ccnxComponentName);

    ccnxComponentName = ccnxName_CreateFromCString(CCNxNameAthena_Link);
    if (ccnxName_StartsWith(ccnxName, ccnxComponentName) == true) {
        responseMessage = _TransportLinkAdapter_Command(athena, interest);
    }
    ccnxName_Release(&ccnxComponentName);

    ccnxComponentName = ccnxName_CreateFromCString(CCNxNameAthena_FIB);
    if (ccnxName_StartsWith(ccnxName, ccnxComponentName) == true) {
        responseMessage = _FIB_Command(athena, interest, ingressVector);
    }
    ccnxName_Release(&ccnxComponentName);

    ccnxComponentName = ccnxName_CreateFromCString(CCNxNameAthena_PIT);
    if (ccnxName_StartsWith(ccnxName, ccnxComponentName) == true) {
        responseMessage = _PIT_Command(athena, interest);
    }
    ccnxName_Release(&ccnxComponentName);

    ccnxComponentName = ccnxName_CreateFromCString(CCNxNameAthena_ContentStore);
    if (ccnxName_StartsWith(ccnxName, ccnxComponentName) == true) {
        responseMessage = _ContentStore_Command(athena, interest);
    }
    ccnxName_Release(&ccnxComponentName);

    if (responseMessage) {
        athena_ProcessMessage(athena, responseMessage, ingressVector);
        ccnxContentObject_Release(&responseMessage);
    }

    return 0;
}
LONGBOW_TEST_CASE(Global, ccnxInterest_SetPayloadWithId)
{
    CCNxName *name = ccnxName_CreateFromURI("lci:/name");
    CCNxInterest *interest = ccnxInterest_CreateSimple(name);
    CCNxName *origNameCopy = ccnxName_Copy(name);

    CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);

    if (impl->getPayload) {
        assertNull(ccnxInterest_GetPayload(interest), "Expected a NULL payload");
    }

    if (impl->getPayload && impl->setPayload) {
        PARCBuffer *payload = parcBuffer_WrapCString("impls have pimples");
        PARCBuffer *payloadIdBuffer = parcBuffer_WrapCString("payload Id buffer");

        CCNxInterestPayloadId *payloadId = ccnxInterestPayloadId_Create(payloadIdBuffer,
                                                                        CCNxInterestPayloadId_TypeCode_App + 2);

        ccnxInterest_SetPayloadWithId(interest, payload, payloadId);

        PARCBuffer *payloadOut = ccnxInterest_GetPayload(interest);

        assertTrue(parcBuffer_Equals(payload, payloadOut), "Expected an equal buffer");

        CCNxName *nameAfterPayload = ccnxInterest_GetName(interest);
        CCNxNameSegment *segment = ccnxName_GetSegment(nameAfterPayload, ccnxName_GetSegmentCount(nameAfterPayload) - 1);

        assertTrue(ccnxNameSegment_GetType(segment) == CCNxNameLabelType_PAYLOADID, "Expected to find a payload ID appended to the name");

        CCNxInterestPayloadId *outId = ccnxInterestPayloadId_CreateFromSegmentInName(nameAfterPayload);
        assertTrue(ccnxInterestPayloadId_Equals(outId, payloadId), "expected to see the same payload Id after setting the payload");

        ccnxInterestPayloadId_Release(&payloadId);
        ccnxInterestPayloadId_Release(&outId);

        parcBuffer_Release(&payload);
        parcBuffer_Release(&payloadIdBuffer);
    }
    ccnxName_Release(&name);
    ccnxName_Release(&origNameCopy);
    ccnxInterest_Release(&interest);
}
Beispiel #17
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;
}
{
    TestData *data = longBowTestCase_GetClipBoardData(testCase);
    data->impl.toString = NULL;

    const char *expectedString = ccnxInterest_ToString(data->interest);
    if (expectedString != NULL) {
        parcMemory_Deallocate((void **) &expectedString);
    }
}

LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetName, .event = &LongBowTrapNotImplemented)
{
    TestData *data = longBowTestCase_GetClipBoardData(testCase);
    data->impl.getName = NULL;

    CCNxName *name = ccnxInterest_GetName(data->interest);
    printf("Shouldn't get here. name = %p\n", (void *) name);
}

LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetHopLimit, .event = &LongBowTrapNotImplemented)
{
    TestData *data = longBowTestCase_GetClipBoardData(testCase);
    data->impl.setHopLimit = NULL;

    if (ccnxInterest_SetHopLimit(data->interest, 10)) {
        printf("Shouldn't get here");
    }
}

LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetHopLimit, .event = &LongBowTrapNotImplemented)
{
Beispiel #19
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);
    }
}