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_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); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }