int cl_version_verify(sr_conn_ctx_t *connection) { int rc = SR_ERR_OK; Sr__Msg *msg_req = NULL, *msg_resp = NULL; sr_mem_ctx_t *sr_mem = NULL; /* prepare version-verification request */ rc = sr_mem_new(0, &sr_mem); CHECK_RC_MSG_GOTO(rc, cleanup, "Failed to create a new Sysrepo memory context."); rc = sr_gpb_req_alloc(sr_mem, SR__OPERATION__VERSION_VERIFY, /* undefined session id */ 0, &msg_req); CHECK_RC_MSG_GOTO(rc, cleanup, "Cannot allocate GPB message."); /* set argument */ sr_mem_edit_string(sr_mem, &msg_req->request->version_verify_req->soname, SR_COMPAT_VERSION); CHECK_NULL_NOMEM_GOTO(msg_req->request->version_verify_req->soname, rc, cleanup); /* send the request */ SR_LOG_DBG("Sending %s request.", sr_gpb_operation_name(SR__OPERATION__VERSION_VERIFY)); pthread_mutex_lock(&connection->lock); rc = cl_message_send(connection, msg_req); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to send the message with request (operation=%s).", sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&connection->lock); goto cleanup; } SR_LOG_DBG("%s request sent, waiting for response.", sr_gpb_operation_name(SR__OPERATION__VERSION_VERIFY)); /* receive the response */ rc = cl_message_recv(connection, &msg_resp, NULL); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to receive the message with response (operation=%s).", sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&connection->lock); goto cleanup; } pthread_mutex_unlock(&connection->lock); SR_LOG_DBG("%s response received, processing.", sr_gpb_operation_name(SR__OPERATION__VERSION_VERIFY)); /* validate the response */ rc = sr_gpb_msg_validate(msg_resp, SR__MSG__MSG_TYPE__RESPONSE, SR__OPERATION__VERSION_VERIFY); if (SR_ERR_OK != rc) { SR_LOG_ERR("Malformed message with response received (operation=%s).", sr_gpb_operation_name(msg_req->request->operation)); goto cleanup; } /* process the result */ if (SR_ERR_OK != msg_resp->response->result) { SR_LOG_ERR("Sysrepod's \"%s\" version is not compatible with version \""SR_COMPAT_VERSION"\" in use.", msg_resp->response->version_verify_resp->soname); rc = msg_resp->response->result; goto cleanup; } cleanup: if (NULL != msg_req) { sr_msg_free(msg_req); } else { sr_mem_free(sr_mem); } if (NULL != msg_resp) { sr_msg_free(msg_resp); } return rc; }
int cl_request_process(sr_session_ctx_t *session, Sr__Msg *msg_req, Sr__Msg **msg_resp, sr_mem_ctx_t *sr_mem_resp, const Sr__Operation expected_response_op) { int rc = SR_ERR_OK; struct timeval tv = { 0, }; CHECK_NULL_ARG4(session, session->conn_ctx, msg_req, msg_resp); SR_LOG_DBG("Sending %s request.", sr_gpb_operation_name(expected_response_op)); pthread_mutex_lock(&session->conn_ctx->lock); /* some operation may take more time, raise the timeout */ if (SR__OPERATION__COMMIT == expected_response_op || SR__OPERATION__COPY_CONFIG == expected_response_op || SR__OPERATION__RPC == expected_response_op || SR__OPERATION__ACTION == expected_response_op) { tv.tv_sec = SR_LONG_REQUEST_TIMEOUT; tv.tv_usec = 0; rc = setsockopt(session->conn_ctx->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); if (-1 == rc) { SR_LOG_WRN("Unable to set timeout for socket operations: %s", sr_strerror_safe(errno)); } } /* send the request */ rc = cl_message_send(session->conn_ctx, msg_req); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to send the message with request (session id=%"PRIu32", operation=%s).", session->id, sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&session->conn_ctx->lock); return rc; } SR_LOG_DBG("%s request sent, waiting for response.", sr_gpb_operation_name(expected_response_op)); /* receive the response */ rc = cl_message_recv(session->conn_ctx, msg_resp, sr_mem_resp); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to receive the message with response (session id=%"PRIu32", operation=%s).", session->id, sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&session->conn_ctx->lock); return rc; } /* change socket timeout to the standard value */ if (SR__OPERATION__COMMIT == expected_response_op || SR__OPERATION__COPY_CONFIG == expected_response_op || SR__OPERATION__RPC == expected_response_op || SR__OPERATION__ACTION == expected_response_op) { tv.tv_sec = SR_REQUEST_TIMEOUT; rc = setsockopt(session->conn_ctx->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); if (-1 == rc) { SR_LOG_WRN("Unable to set timeout for socket operations: %s", sr_strerror_safe(errno)); } } pthread_mutex_unlock(&session->conn_ctx->lock); SR_LOG_DBG("%s response received, processing.", sr_gpb_operation_name(expected_response_op)); /* validate the response */ rc = sr_gpb_msg_validate(*msg_resp, SR__MSG__MSG_TYPE__RESPONSE, expected_response_op); if (SR_ERR_OK != rc) { SR_LOG_ERR("Malformed message with response received (session id=%"PRIu32", operation=%s).", session->id, sr_gpb_operation_name(msg_req->request->operation)); return rc; } /* check for errors */ if (SR_ERR_OK != (*msg_resp)->response->result) { if (NULL != (*msg_resp)->response->error) { /* set detailed error information into session */ rc = cl_session_set_error(session, (*msg_resp)->response->error->message, (*msg_resp)->response->error->xpath); } /* log the error (except expected ones) */ if (SR_ERR_NOT_FOUND != (*msg_resp)->response->result && SR_ERR_VALIDATION_FAILED != (*msg_resp)->response->result && SR_ERR_UNAUTHORIZED != (*msg_resp)->response->result && SR_ERR_OPERATION_FAILED != (*msg_resp)->response->result) { SR_LOG_ERR("Error by processing of the %s request (session id=%"PRIu32"): %s.", sr_gpb_operation_name(msg_req->request->operation), session->id, (NULL != (*msg_resp)->response->error && NULL != (*msg_resp)->response->error->message) ? (*msg_resp)->response->error->message : sr_strerror((*msg_resp)->response->result)); } return (*msg_resp)->response->result; } return rc; }
int cl_request_process(sr_session_ctx_t *session, Sr__Msg *msg_req, Sr__Msg **msg_resp, sr_mem_ctx_t *sr_mem_resp, const Sr__Operation expected_response_op) { int rc = SR_ERR_OK; CHECK_NULL_ARG4(session, session->conn_ctx, msg_req, msg_resp); SR_LOG_DBG("Sending %s request.", sr_gpb_operation_name(expected_response_op)); pthread_mutex_lock(&session->conn_ctx->lock); /* send the request */ rc = cl_message_send(session->conn_ctx, msg_req); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to send the message with request (session id=%"PRIu32", operation=%s).", session->id, sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&session->conn_ctx->lock); return rc; } SR_LOG_DBG("%s request sent, waiting for response.", sr_gpb_operation_name(expected_response_op)); /* receive the response */ rc = cl_message_recv(session->conn_ctx, msg_resp, sr_mem_resp); if (SR_ERR_OK != rc) { SR_LOG_ERR("Unable to receive the message with response (session id=%"PRIu32", operation=%s).", session->id, sr_gpb_operation_name(msg_req->request->operation)); pthread_mutex_unlock(&session->conn_ctx->lock); return rc; } pthread_mutex_unlock(&session->conn_ctx->lock); SR_LOG_DBG("%s response received, processing.", sr_gpb_operation_name(expected_response_op)); /* validate the response */ rc = sr_gpb_msg_validate(*msg_resp, SR__MSG__MSG_TYPE__RESPONSE, expected_response_op); if (SR_ERR_OK != rc) { SR_LOG_ERR("Malformed message with response received (session id=%"PRIu32", operation=%s).", session->id, sr_gpb_operation_name(msg_req->request->operation)); return rc; } /* check for errors */ if (SR_ERR_OK != (*msg_resp)->response->result) { if (NULL != (*msg_resp)->response->error) { /* set detailed error information into session */ rc = cl_session_set_error(session, (*msg_resp)->response->error->message, (*msg_resp)->response->error->xpath); } /* log the error (except expected ones) */ if (SR_ERR_NOT_FOUND != (*msg_resp)->response->result && SR_ERR_VALIDATION_FAILED != (*msg_resp)->response->result && SR_ERR_UNAUTHORIZED != (*msg_resp)->response->result && SR_ERR_OPERATION_FAILED != (*msg_resp)->response->result) { SR_LOG_ERR("Error by processing of the %s request (session id=%"PRIu32"): %s.", sr_gpb_operation_name(msg_req->request->operation), session->id, (NULL != (*msg_resp)->response->error && NULL != (*msg_resp)->response->error->message) ? (*msg_resp)->response->error->message : sr_strerror((*msg_resp)->response->result)); } return (*msg_resp)->response->result; } return rc; }