Ejemplo n.º 1
0
static Sr__Msg *
cm_message_recv(const int fd)
{
    uint8_t buf1[SR_MSG_PREAM_SIZE] = { 0, }, *buf2 = NULL;
    size_t len = 0, pos = 0;
    size_t msg_size = 0;

    /* read first 4 bytes with length of the message */
    while (pos < SR_MSG_PREAM_SIZE) {
        len = recv(fd, buf1 + pos, SR_MSG_PREAM_SIZE - pos, 0);
        assert_int_not_equal(len, -1);
        if (0 == len) {
            return NULL; /* disconnect */
        }
        pos += len;
    }
    msg_size = sr_buff_to_uint32(buf1);
    assert_true((msg_size > 0) && (msg_size <= SR_MAX_MSG_SIZE));

    buf2 = calloc(msg_size, sizeof(*buf2));
    assert_non_null(buf2);

    /* read the rest of the message */
    pos = 0;
    while (pos < msg_size) {
        len = recv(fd, buf2 + pos, msg_size - pos, 0);
        assert_int_not_equal(len, -1);
        if (0 == len) {
            return NULL; /* disconnect */
        }
        pos += len;
    }

    Sr__Msg *msg = sr__msg__unpack(NULL, msg_size, (const uint8_t*)buf2);
    free(buf2);
    return msg;
}
Ejemplo n.º 2
0
/*
 * @brief Receives a message on provided connection (blocks until a message is received).
 */
static int
cl_message_recv(sr_conn_ctx_t *conn_ctx, Sr__Msg **msg, sr_mem_ctx_t *sr_mem_resp)
{
    size_t len = 0, pos = 0;
    size_t msg_size = 0;
    sr_mem_ctx_t *sr_mem = sr_mem_resp;
    int rc = 0;

    /* expand the buffer if needed */
    rc = cl_conn_msg_buf_expand(conn_ctx, SR_MSG_PREAM_SIZE);
    if (SR_ERR_OK != rc) {
        SR_LOG_ERR_MSG("Cannot expand buffer for the message.");
        return rc;
    }

    /* read at least first 4 bytes with length of the message */
    while (pos < SR_MSG_PREAM_SIZE) {
        len = recv(conn_ctx->fd, conn_ctx->msg_buf, conn_ctx->msg_buf_size, 0);
        if (-1 == len) {
            if (errno == EINTR) {
                continue;
            }
            if (EAGAIN == errno || EWOULDBLOCK == errno) {
                SR_LOG_ERR_MSG("While waiting for a response, timeout has expired.");
                return SR_ERR_TIME_OUT;
            }
            SR_LOG_ERR("Error by receiving of the message: %s.", sr_strerror_safe(errno));
            return SR_ERR_DISCONNECT;
        }
        if (0 == len) {
            SR_LOG_ERR_MSG("Sysrepo server disconnected.");
            return SR_ERR_DISCONNECT;
        }
        pos += len;
    }
    msg_size = sr_buff_to_uint32(conn_ctx->msg_buf);

    /* check message size bounds */
    if ((msg_size <= 0) || (msg_size > SR_MAX_MSG_SIZE)) {
        SR_LOG_ERR("Invalid message size in the message preamble (%zu).", msg_size);
        return SR_ERR_MALFORMED_MSG;
    }

    /* expand the buffer if needed */
    rc = cl_conn_msg_buf_expand(conn_ctx, (msg_size + SR_MSG_PREAM_SIZE));
    if (SR_ERR_OK != rc) {
        SR_LOG_ERR_MSG("Cannot expand buffer for the message.");
        return rc;
    }

    /* read the rest of the message */
    while (pos < (msg_size + SR_MSG_PREAM_SIZE)) {
        len = recv(conn_ctx->fd, (conn_ctx->msg_buf + pos), (conn_ctx->msg_buf_size - pos), 0);
        if (-1 == len) {
            if (errno == EINTR) {
                continue;
            }
            if (EAGAIN == errno || EWOULDBLOCK == errno) {
                SR_LOG_ERR_MSG("While waiting for a response, timeout has expired.");
                return SR_ERR_TIME_OUT;
            }
            SR_LOG_ERR("Error by receiving of the message: %s.", sr_strerror_safe(errno));
            return SR_ERR_DISCONNECT;
        }
        if (0 == len) {
            SR_LOG_ERR_MSG("Sysrepo server disconnected.");
            return SR_ERR_DISCONNECT;
        }
        pos += len;
    }

    /* unpack the message */
    if (NULL == sr_mem) {
        rc = sr_mem_new(msg_size, &sr_mem);
        CHECK_RC_MSG_RETURN(rc, "Failed to create a new Sysrepo memory context.");
    }
    ProtobufCAllocator allocator = sr_get_protobuf_allocator(sr_mem);
    *msg = sr__msg__unpack(&allocator, msg_size, (const uint8_t*)(conn_ctx->msg_buf + SR_MSG_PREAM_SIZE));
    if (NULL == *msg) {
        if (NULL == sr_mem_resp) {
            sr_mem_free(sr_mem);
        }
        SR_LOG_ERR_MSG("Malformed message received.");
        return SR_ERR_MALFORMED_MSG;
    }

    /* associate message with context */
    if (NULL != sr_mem) {
        (*msg)->_sysrepo_mem_ctx = (uint64_t)sr_mem;
        ++sr_mem->obj_count;
    }

    return SR_ERR_OK;
}