예제 #1
0
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;
}
예제 #2
0
/*
 * 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);
    }
}
예제 #3
0
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;
}
예제 #4
0
/*
 * 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));
    }
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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);
}
예제 #10
0
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);
    }
}
예제 #11
0
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;
}
예제 #12
0
파일: metis_daemon.c 프로젝트: isolis/Metis
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
}