Example #1
0
static void inFromChildDecode(struct Admin* admin, struct Admin_Channel* channel)
{
    uint8_t* buffer = channel->buffer;
    uint32_t bufferLen = channel->bufferLen;

    union Admin_TxidPrefix prefix = {
        .values = {
            .channelNum = admin->messageHeader.channelNum,
            .serial = channel->serial
        }
    };

    while (bufferLen > 0) {
        /* skip newlines and spaces between requests */
        while (bufferLen > 0 && ('\r' == *buffer || '\n' == *buffer || ' ' == *buffer)) {
            buffer++;
            bufferLen--;
        }
        if (0 == bufferLen) {
            break;
        }

        struct Allocator* allocator = admin->allocator->child(admin->allocator);

        struct Reader* reader = ArrayReader_new(buffer, bufferLen, allocator);
        Dict message;

        int res = StandardBencSerializer_get()->parseDictionary(reader, allocator, &message);
        if (-2 == res) {
            Log_debug(admin->logger,
                      "Need more data to decode bencoded request on channel [%u].",
                      admin->messageHeader.channelNum);
            break; // need more data
        }
        if (res) {
            Log_info(admin->logger,
                     "Got unparsable data from admin interface on channel [%u].",
                     admin->messageHeader.channelNum);
            adminChannelClose(admin, admin->messageHeader.channelNum);
            return; // buffer is already cleared
        }

        uint32_t amount = reader->bytesRead(reader);

        handleRequestFromChild(admin, &prefix, &message, buffer, amount, allocator);
        buffer += amount;
        bufferLen -= amount;

        allocator->free(allocator);
    }

    if (0 != bufferLen && buffer != channel->buffer) {
        // move data to start of buffer, so we can append new data
        memmove(channel->buffer, buffer, bufferLen);
    }
    channel->bufferLen = bufferLen;
}
Example #2
0
// only in parent
static void inFromChild(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct Admin* admin = (struct Admin*) vcontext;

    uint8_t buffer[MAX_API_REQUEST_SIZE];
    ssize_t amount = read(admin->inFd, buffer, MAX_API_REQUEST_SIZE);

    if (amount < 1) {
        if (amount == 0 || errno != EAGAIN) {
            perror("broken pipe");
            event_free(admin->pipeEv);
        }
        return;
    }

    struct Allocator* tempAllocator = admin->allocator->child(admin->allocator);
    handleRequestFromChild(admin, buffer, amount, tempAllocator);
    tempAllocator->free(tempAllocator);
}
Example #3
0
// only in parent
static void inFromChild(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct Admin* admin = (struct Admin*) vcontext;

    uint8_t buffer[MAX_API_REQUEST_SIZE];
    ssize_t amount = read(admin->inFd, buffer, MAX_API_REQUEST_SIZE);

    if (amount < 1) {
        if (amount == 0 || errno != EAGAIN) {
            if (amount < 0) {
                Log_error1(admin->logger, "Broken pipe to admin process, errno=%d", errno);
            } else {
                Log_error(admin->logger, "Connection to admin process closed unexpectedly");
            }
            event_free(admin->pipeEv);
        }
        return;
    }

    if (!admin->initialized) {
        if (amount != sizeof(struct sockaddr_storage) + sizeof(int) + 8) {
            Log_error(admin->logger, "unexpected length");
        } else if (memcmp(buffer, "abcd", 4)) {
            Log_error(admin->logger, "bad magic");
        } else if (memcmp(&buffer[sizeof(struct sockaddr_storage) + sizeof(int) + 4], "wxyz", 4)) {
            Log_error(admin->logger, "bad magic");
        } else {
            Bits_memcpyConst(&admin->addressLength, &buffer[4], sizeof(int));
            Bits_memcpyConst(&admin->address,
                             &buffer[4 + sizeof(int)],
                             sizeof(struct sockaddr_storage));
            admin->initialized = true;
        }
        event_base_loopbreak(admin->eventBase);
        return;
    }

    struct Allocator* tempAllocator = admin->allocator->child(admin->allocator);
    handleRequestFromChild(admin, buffer, amount, tempAllocator);
    tempAllocator->free(tempAllocator);
}