static bool _parse(MetisTlvSkeleton *skeleton) { _MetisTlvFixedHeaderV0 *hdr = (_MetisTlvFixedHeaderV0 *) metisTlvSkeleton_GetPacket(skeleton); size_t headerLength = htons(hdr->headerLength); size_t endHeaders = FIXED_HEADER_LEN + headerLength; size_t endPacket = TotalPacketLength(hdr); trapUnexpectedStateIf(hdr->version != 0, "Version not 0"); switch (hdr->packetType) { case METIS_PACKET_TYPE_INTEREST: _parsePerHopV0(metisTlvSkeleton_GetPacket(skeleton), FIXED_HEADER_LEN, endHeaders, skeleton); _parseInterestV0(metisTlvSkeleton_GetPacket(skeleton), endHeaders, endPacket, skeleton); break; case METIS_PACKET_TYPE_CONTENT: _parsePerHopV0(metisTlvSkeleton_GetPacket(skeleton), FIXED_HEADER_LEN, endHeaders, skeleton); _parseObjectV0(metisTlvSkeleton_GetPacket(skeleton), endHeaders, endPacket, skeleton); break; case METIS_PACKET_TYPE_CONTROL: _parseControlPlaneInterface(metisTlvSkeleton_GetPacket(skeleton), endHeaders, endPacket, skeleton); break; default: break; } return true; }
/* * In the Busy state, we can only accept a packet with no flag (middle) or end flag (end of packet). * Anything else is an error and will cause the parser to be reset. * * 1) If no flags * 1a) append to reassembly buffer * 2) If E flag * 2a) append to reassembly buffer * 2b) finalize the buffer (side effect: will reset the parser and place in receive queue) * 3) Otherwise, its an error, reset the parser * * PRECONDITION: you know the packet is in-order relative to the assembly buffer. * This is handled by calling _applySequenceNumberRules() before this function. * PRECONDITION: you know the parser is in the Busy state. */ static void _receiveInBusyState(MetisHopByHopFragmenter *fragmenter, const MetisMessage *message, const _HopByHopHeader *fixedHeader) { trapUnexpectedStateIf(fragmenter->parserState != _ParserState_Busy, "Parser in wrong state, expected %d got %d", _ParserState_Busy, fragmenter->parserState); if (_hopByHopHeader_GetFlags(fixedHeader) == 0) { // It's a middle packet _appendFragmentToReassemblyBuffer(fragmenter, message); } else if (_hopByHopHeader_GetEFlag(fixedHeader)) { // It is the last fragment _appendFragmentToReassemblyBuffer(fragmenter, message); _finalizeReassemblyBuffer(fragmenter); } else { // nothing we can do with this frame, and it's a state machine error metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Warning, __func__, "Fragmenter %p received invalid headers (0x%02X) in Busy state, resetting", (void *) fragmenter, _hopByHopHeader_GetFlags(fixedHeader)); _resetParser(fragmenter); } }
static bool _parse(MetisTlvSkeleton *skeleton) { bool success = false; _MetisTlvFixedHeaderV1 *hdr = (_MetisTlvFixedHeaderV1 *) metisTlvSkeleton_GetPacket(skeleton); // this function should only be called for version 1 packets trapUnexpectedStateIf(hdr->version != 1, "Version not 1"); if (_goodPacketType(hdr->packetType) && hdr->headerLength >= sizeof(_MetisTlvFixedHeaderV1)) { size_t endHeaders = hdr->headerLength; size_t endPacket = htons(hdr->packetLength); if (endPacket >= endHeaders) { if (_isPacketTypeInterest((uint8_t *) hdr)) { metisTlvSkeleton_SetHopLimit(skeleton, 4, 1); } _parsePerHopV1(metisTlvSkeleton_GetPacket(skeleton), sizeof(_MetisTlvFixedHeaderV1), endHeaders, skeleton); size_t offset = _parseMessage(metisTlvSkeleton_GetPacket(skeleton), endHeaders, endPacket, skeleton); _parseValidationAlg(metisTlvSkeleton_GetPacket(skeleton), offset, endPacket, skeleton); success = true; } } return success; }
/* * Parser is in Idle state. We can only accept a B or BE frame. * 1) If B frame: * 1a) append to current receive buffer * 1b) set parser state to Busy * 1c) set the currentReceiveBufferStartTicks * 1d) set the currentReceiveBufferIngressId * 2) If BE frame, do B actions and finalize it (side effect: will reset state to Idle) * 3) Otherwise ignore it * * Precondition: You know that the parser is in the Idle state */ static void _receiveInIdleState(MetisHopByHopFragmenter *fragmenter, const MetisMessage *message, const _HopByHopHeader *fixedHeader) { trapUnexpectedStateIf(fragmenter->parserState != _ParserState_Idle, "Parser in wrong state, expected %d got %d", _ParserState_Idle, fragmenter->parserState); if (_hopByHopHeader_GetBFlag(fixedHeader)) { // start a new packet fragmenter->currentReceiveBufferStartTicks = metisMessage_GetReceiveTime(message); fragmenter->currentReceiveBufferIngressId = metisMessage_GetIngressConnectionId(message); fragmenter->parserState = _ParserState_Busy; _appendFragmentToReassemblyBuffer(fragmenter, message); if (_hopByHopHeader_GetEFlag(fixedHeader)) { // it is also the last fragment _finalizeReassemblyBuffer(fragmenter); } } else if (_hopByHopHeader_GetIFlag(fixedHeader)) { // nothing to do metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Debug, __func__, "Fragmenter %p idle frame, ignorning", (void *) fragmenter); } else { // nothing we can do with this frame metisLogger_Log(fragmenter->logger, MetisLoggerFacility_IO, PARCLogLevel_Warning, __func__, "Fragmenter %p received bad header flags (0x%02X), ignorning", (void *) fragmenter, _hopByHopHeader_GetFlags(fixedHeader)); } }
PARCJSON * parcJSONValue_GetJSON(const PARCJSONValue *value) { parcJSONValue_OptionalAssertValid(value); trapUnexpectedStateIf(!parcJSONValue_IsJSON(value), "Expected type to be string, actual type %d", value->type); return value->value.object; }
PARCBuffer * parcJSONValue_GetString(const PARCJSONValue *value) { parcJSONValue_OptionalAssertValid(value); trapUnexpectedStateIf(!parcJSONValue_IsString(value), "Expected type to be string, actual type %d", value->type); return value->value.string; }
bool parcJSONValue_GetBoolean(const PARCJSONValue *value) { parcJSONValue_OptionalAssertValid(value); trapUnexpectedStateIf(!parcJSONValue_IsBoolean(value), "Expected type to be boolean, actual type %d", value->type); return value->value.boolean; }
PARCJSONArray * parcJSONValue_GetArray(const PARCJSONValue *value) { parcJSONValue_OptionalAssertValid(value); trapUnexpectedStateIf(!parcJSONValue_IsArray(value), "Expected type to be array, actual type %d", value->type); return value->value.array; }
void parcLock_Notify(PARCLock *lock) { parcLock_OptionalAssertValid(lock); trapUnexpectedStateIf(lock->locked == false, "You must Lock the object before calling parcLock_Notify"); lock->notified = true; pthread_cond_signal(&lock->notification); }
void parcLock_Wait(PARCLock *lock) { parcLock_OptionalAssertValid(lock); trapUnexpectedStateIf(lock->locked == false, "You must Lock the object before calling parcLock_Wait"); lock->notified = false; while (lock->notified == false) { pthread_cond_wait(&lock->notification, &lock->lock); } }
static void _addContentStoreEntryToLRUHead(AthenaLRUContentStore *impl, _AthenaLRUContentStoreEntry *entry) { trapUnexpectedStateIf(impl->lruHead != NULL && impl->lruHead->prev != NULL, "Unexpected LRU pointer configuration. Next should be NULL."); if (impl->lruTail == NULL) { impl->lruTail = entry; } if (impl->lruHead != NULL) { impl->lruHead->prev = entry; } entry->next = impl->lruHead; entry->prev = NULL; impl->lruHead = entry; }
static void _daemonize(void) { if (getppid() == 1) { // already a daemon return; } int forkReturn = fork(); trapUnexpectedStateIf(forkReturn < 0, "Fork error"); if (forkReturn > 0) { // parent exits exit(EXIT_SUCCESS); } // Child daemon detaches printf("child continuing, pid = %u\n", getpid()); // get a new process group independent from old parent setsid(); /* close all descriptors */ for (int i = getdtablesize(); i >= 0; --i) { close(i); } // reset errno because it might be seg to EBADF from the close calls above errno = 0; // Redirect stdin and stdout and stderr to /dev/null const char *devnull = "/dev/null"; int nullfile = open(devnull, O_RDWR); assertTrue(nullfile >= 0, "Error opening file '%s': (%d) %s", devnull, errno, strerror(errno)); int ret; ret = dup(nullfile); assertTrue(ret == 1, "Error duping fd 1 got %d file: (%d) %s", ret, errno, strerror(errno)); ret = dup(nullfile); assertTrue(ret == 2, "Error duping fd 2, got %d file: (%d) %s", ret, errno, strerror(errno)); // metisForwarder will capture signals }