Exemple #1
0
static CCNxMetaMessage *
_Control_Command_Set(Athena *athena, CCNxName *ccnxName, const char *command)
{
    CCNxMetaMessage *responseMessage = NULL;

    if (ccnxName_GetSegmentCount(ccnxName) <= (AthenaCommandSegment + 2)) {
        responseMessage = _create_response(athena, ccnxName, "Athena set arguments required <name> <value>");
        return responseMessage;
    }
    // Check for required set name argument
    CCNxNameSegment *nameSegment = ccnxName_GetSegment(ccnxName, AthenaCommandSegment + 1);
    char *name = ccnxNameSegment_ToString(nameSegment);
    if (strcasecmp(name, AthenaCommand_LogLevel) == 0) {
        // Check the level to set the log to
        nameSegment = ccnxName_GetSegment(ccnxName, AthenaCommandSegment + 2);
        char *level = ccnxNameSegment_ToString(nameSegment);
        if (strcasecmp(level, AthenaCommand_LogDebug) == 0) {
            athenaTransportLinkAdapter_SetLogLevel(athena->athenaTransportLinkAdapter, PARCLogLevel_Debug);
            parcLog_SetLevel(athena->log, PARCLogLevel_Debug);
            athenaInterestControl_LogConfigurationChange(athena, ccnxName, NULL);
            responseMessage = _create_response(athena, ccnxName, "set athena logging level to %s", AthenaCommand_LogDebug);
        } else if (strcasecmp(level, AthenaCommand_LogInfo) == 0) {
            athenaTransportLinkAdapter_SetLogLevel(athena->athenaTransportLinkAdapter, PARCLogLevel_Info);
            parcLog_SetLevel(athena->log, PARCLogLevel_Info);
            athenaInterestControl_LogConfigurationChange(athena, ccnxName, NULL);
            responseMessage = _create_response(athena, ccnxName, "set athena logging level to %s", AthenaCommand_LogInfo);
        } else if (strcasecmp(level, AthenaCommand_LogOff) == 0) {
            athenaTransportLinkAdapter_SetLogLevel(athena->athenaTransportLinkAdapter, PARCLogLevel_Off);
            parcLog_SetLevel(athena->log, PARCLogLevel_Off);
            athenaInterestControl_LogConfigurationChange(athena, ccnxName, NULL);
            responseMessage = _create_response(athena, ccnxName, "set athena logging level to %s", AthenaCommand_LogOff);
        } else if (strcasecmp(level, AthenaCommand_LogAll) == 0) {
            athenaTransportLinkAdapter_SetLogLevel(athena->athenaTransportLinkAdapter, PARCLogLevel_All);
            parcLog_SetLevel(athena->log, PARCLogLevel_All);
            athenaInterestControl_LogConfigurationChange(athena, ccnxName, NULL);
            responseMessage = _create_response(athena, ccnxName, "set athena logging level to %s", AthenaCommand_LogAll);
        } else if (strcasecmp(level, AthenaCommand_LogError) == 0) {
            athenaTransportLinkAdapter_SetLogLevel(athena->athenaTransportLinkAdapter, PARCLogLevel_Error);
            parcLog_SetLevel(athena->log, PARCLogLevel_Error);
            athenaInterestControl_LogConfigurationChange(athena, ccnxName, NULL);
            responseMessage = _create_response(athena, ccnxName, "set athena logging level to %s", AthenaCommand_LogError);
        } else if (strcasecmp(level, AthenaCommand_LogNotice) == 0) {
            athenaTransportLinkAdapter_SetLogLevel(athena->athenaTransportLinkAdapter, PARCLogLevel_Notice);
            parcLog_SetLevel(athena->log, PARCLogLevel_Notice);
            athenaInterestControl_LogConfigurationChange(athena, ccnxName, NULL);
            responseMessage = _create_response(athena, ccnxName, "set athena logging level to %s", AthenaCommand_LogNotice);
        } else {
            responseMessage = _create_response(athena, ccnxName, "unknown logging level (%s)", level);
        }
        parcMemory_Deallocate(&level);
    } else {
        responseMessage = _create_response(athena, ccnxName, "Athena unknown set name (%s)", name);
    }

    parcMemory_Deallocate(&name);
    return responseMessage;
}
Exemple #2
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;
}
Exemple #3
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;
}
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);
}
Exemple #5
0
MetisTlvName *
metisTlvName_CreateFromCCNxName(const CCNxName *ccnxName)
{
    // to avoid reallocs, calculate the exact size we need
    size_t memoryLength = 0;
    for (size_t i = 0; i < ccnxName_GetSegmentCount(ccnxName); i++) {
        CCNxNameSegment *segment = ccnxName_GetSegment(ccnxName, i);
        memoryLength += 4 + ccnxNameSegment_Length(segment);
    }

    MetisTlvName *name = parcMemory_AllocateAndClear(sizeof(MetisTlvName));
    assertNotNull(name, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(MetisTlvName));

    name->memoryLength = memoryLength;
    name->memory = parcMemory_Allocate(memoryLength);
    assertNotNull(name->memory, "parcMemory_Allocate(%zu) returned NULL", memoryLength);

    uint8_t *p = name->memory;
    uint8_t *end = p + memoryLength;
    for (size_t i = 0; i < ccnxName_GetSegmentCount(ccnxName); i++) {
        CCNxNameSegment *segment = ccnxName_GetSegment(ccnxName, i);
        uint16_t type = ccnxNameSegment_GetType(segment);
        uint16_t length = ccnxNameSegment_Length(segment);

        *(uint16_t *) p = htons(type);
        p += 2;

        *(uint16_t *) p = htons(length);
        p += 2;

        if (length >0) {
            PARCBuffer *buffer = ccnxNameSegment_GetValue(segment);
            uint8_t *overlay = parcBuffer_Overlay(buffer, 0);
            memcpy(p, overlay, length);

            p += length;
        }

        // sanity check
        assertTrue(p <= end, "Wrote past the end of buffer, now at %p end at %p", p, end);
    }

    _setup(name);
    return name;
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
0
static void
_getChunkNumberFromName(const CCNxName *name, uint64_t *chunkNum, bool *hasChunkNum)
{
    // XXX: This could be a utility in CCNxName.

    size_t numSegments = ccnxName_GetSegmentCount(name);
    CCNxNameSegment *lastSeg = ccnxName_GetSegment(name, numSegments - 1);

    if (ccnxNameSegment_GetType(lastSeg) == CCNxNameLabelType_CHUNK) {
        *hasChunkNum = true;
        *chunkNum = ccnxNameSegmentNumber_Value(lastSeg);
    } else {
        *hasChunkNum = false;
        *chunkNum = 0;
    }
}
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;
}
Exemple #10
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
}
CCNxInterestPayloadId *
ccnxInterestPayloadId_CreateFromSegmentInName(const CCNxName *name)
{
    ccnxName_AssertValid(name);

    CCNxInterestPayloadId *result = NULL;
    size_t count = ccnxName_GetSegmentCount(name);
    for (size_t i = 0; i < count; ++i) {
        CCNxNameSegment *segment = ccnxName_GetSegment(name, i);
        if (ccnxNameSegment_GetType(segment) == CCNxNameLabelType_PAYLOADID) {
            result = _ccnxInterestPayloadId_CreateFromNameSegment(segment);
            break;
        }
    }

    return result;
}
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);
}
Exemple #13
0
static bool
_getSegmentIndexOfQueryArgs(CCNxName *name, char *nameString, size_t *segmentNumber)
{
    bool result = false;
    size_t numSegments = ccnxName_GetSegmentCount(name);
    size_t curSegment = 0;
    while (curSegment < numSegments) {
        CCNxNameSegment *segment = ccnxName_GetSegment(name, curSegment);
        if (ccnxNameSegment_GetType(segment) == CCNxNameLabelType_NAME) {
            char *segString = ccnxNameSegment_ToString(segment);
            if (strncasecmp(segString, nameString, strlen(nameString)) == 0) {
                parcMemory_Deallocate(&segString);
                *segmentNumber = curSegment + 1;
                result = true;
                break;
            }
            parcMemory_Deallocate(&segString);
            curSegment++;
        }
    }
    return result;
}
Exemple #14
0
static PARCBuffer *
_processStatQuery(const AthenaLRUContentStore *impl, CCNxName *queryName, size_t argIndex, uint64_t chunkNumber)
{
    PARCBuffer *result = NULL;

    if (argIndex < ccnxName_GetSegmentCount(queryName)) {
        CCNxNameSegment *segment = ccnxName_GetSegment(queryName, argIndex);
        char *queryString = ccnxNameSegment_ToString(segment);

        char *sizeString = "size";
        char *hitsString = "hits";

        if (strncasecmp(queryString, sizeString, strlen(sizeString)) == 0) {
            result = _createStatSizeResponsePayload(impl, queryName, chunkNumber);
        } else if (strncasecmp(queryString, hitsString, strlen(hitsString)) == 0) {
            result = _createStatHitsResponsePayload(impl, queryName, chunkNumber);
        }

        parcMemory_Deallocate(&queryString);
    }
    return result;
}
Exemple #15
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;
}