Esempio n. 1
0
int
qdevice_heuristics_cmd_write_exec_list(struct qdevice_heuristics_instance *instance,
    const struct qdevice_heuristics_exec_list *new_exec_list)
{
	struct send_buffer_list_entry *send_buffer;
	struct qdevice_heuristics_exec_list_entry *entry;

	send_buffer = send_buffer_list_get_new(&instance->cmd_out_buffer_list);
	if (send_buffer == NULL) {
		qdevice_log(LOG_ERR, "Can't alloc send list for cmd change exec list");

		return (-1);
	}

	if (dynar_str_cpy(&send_buffer->buffer, QDEVICE_HEURISTICS_CMD_STR_EXEC_LIST_CLEAR) == -1 ||
	    dynar_str_cat(&send_buffer->buffer, "\n") == -1) {
		qdevice_log(LOG_ERR, "Can't alloc list clear message");

		send_buffer_list_discard_new(&instance->cmd_out_buffer_list, send_buffer);

		return (-1);
	}

	send_buffer_list_put(&instance->cmd_out_buffer_list, send_buffer);

	if (new_exec_list == NULL) {
		return (0);
	}

	/*
	 * new_exec_list is not NULL, send it
	 */
	TAILQ_FOREACH(entry, new_exec_list, entries) {
		send_buffer = send_buffer_list_get_new(&instance->cmd_out_buffer_list);
		if (send_buffer == NULL) {
			qdevice_log(LOG_ERR, "Can't alloc send list for cmd change exec list");

			return (-1);
		}

		if (dynar_str_cpy(&send_buffer->buffer,
		    QDEVICE_HEURISTICS_CMD_STR_EXEC_LIST_ADD_SPACE) == -1 ||
		    dynar_str_cat(&send_buffer->buffer, entry->name) == -1 ||
		    dynar_str_cat(&send_buffer->buffer, " ") == -1 ||
		    dynar_str_cat(&send_buffer->buffer, entry->command) == -1 ||
		    qdevice_heuristics_cmd_remove_newlines(&send_buffer->buffer) == -1 ||
		    dynar_str_cat(&send_buffer->buffer, "\n") == -1) {
			qdevice_log(LOG_ERR, "Can't alloc list add message");

			send_buffer_list_discard_new(&instance->cmd_out_buffer_list, send_buffer);

			return (-1);
		}

		send_buffer_list_put(&instance->cmd_out_buffer_list, send_buffer);
	}
static int
qdevice_net_msg_received_vote_info(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg)
{
	struct send_buffer_list_entry *send_buffer;
	enum tlv_vote result_vote;
	int ring_id_is_valid;

	if (instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) {
		qdevice_log(LOG_ERR, "Received unexpected vote info message. "
		    "Disconnecting from server");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_UNEXPECTED_MSG;
		return (-1);
	}

	if (!msg->vote_set || !msg->seq_number_set || !msg->ring_id_set) {
		qdevice_log(LOG_ERR, "Received node list reply message without "
		    "required options. Disconnecting from server");
		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;
		return (-1);
	}

	qdevice_log(LOG_DEBUG, "Received vote info");
	qdevice_log(LOG_DEBUG, "  seq = "UTILS_PRI_MSG_SEQ, msg->seq_number);
	qdevice_log(LOG_DEBUG, "  vote = %s", tlv_vote_to_str(msg->vote));
	qdevice_log(LOG_DEBUG, "  ring id = ("UTILS_PRI_RING_ID")",
		    msg->ring_id.node_id, msg->ring_id.seq);

	result_vote = msg->vote;

	if (!tlv_ring_id_eq(&msg->ring_id, &instance->last_sent_ring_id)) {
		ring_id_is_valid = 0;
		qdevice_log(LOG_DEBUG, "Received vote info with old ring id.");
	} else {
		ring_id_is_valid = 1;
	}

	if (qdevice_net_algorithm_vote_info_received(instance, msg->seq_number,
	    &msg->ring_id, ring_id_is_valid, &result_vote) != 0) {
		qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting.");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTE_INFO_ERR;
		return (-1);
	} else {
		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
	}

	if (qdevice_net_cast_vote_timer_update(instance, result_vote) != 0) {
		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER;
		return (-1);
	}

	/*
	 * Create reply message
	 */
	send_buffer = send_buffer_list_get_new(&instance->send_buffer_list);
	if (send_buffer == NULL) {
		qdevice_log(LOG_ERR, "Can't allocate send list buffer for "
		    "vote info reply msg");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;
		return (-1);
	}

	if (msg_create_vote_info_reply(&send_buffer->buffer, msg->seq_number) == 0) {
		qdevice_log(LOG_ERR, "Can't allocate send buffer for "
		    "vote info reply list msg");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;
		send_buffer_list_discard_new(&instance->send_buffer_list, send_buffer);
		return (-1);
	}

	send_buffer_list_put(&instance->send_buffer_list, send_buffer);

	return (0);
}
static int
qdevice_net_msg_received_preinit_reply(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg)
{
	int res;
	struct send_buffer_list_entry *send_buffer;

	qdevice_log(LOG_DEBUG, "Received preinit reply msg");

	if (instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_PREINIT_REPLY) {
		qdevice_log(LOG_ERR, "Received unexpected preinit reply message. "
		    "Disconnecting from server");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_UNEXPECTED_MSG;

		return (-1);
	}

	if (qdevice_net_msg_check_seq_number(instance, msg) != 0) {
		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;

		return (-1);
	}

	/*
	 * Check TLS support
	 */
	if (!msg->tls_supported_set || !msg->tls_client_cert_required_set) {
		qdevice_log(LOG_ERR, "Required tls_supported or tls_client_cert_required "
		    "option is unset");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;

		return (-1);
	}

	res = qdevice_net_msg_received_check_tls_compatibility(msg->tls_supported, instance->tls_supported);
	if (res == -1) {
		qdevice_log(LOG_ERR, "Incompatible tls configuration (server %u client %u)",
		    msg->tls_supported, instance->tls_supported);

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_INCOMPATIBLE_TLS;

		return (-1);
	} else if (res == 1) {
		/*
		 * Start TLS
		 */
		send_buffer = send_buffer_list_get_new(&instance->send_buffer_list);
		if (send_buffer == NULL) {
			qdevice_log(LOG_ERR, "Can't allocate send list buffer for "
			    "starttls msg");

			instance->disconnect_reason =
			    QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;

			return (-1);
		}

		instance->last_msg_seq_num++;
		if (msg_create_starttls(&send_buffer->buffer, 1,
		    instance->last_msg_seq_num) == 0) {
			qdevice_log(LOG_ERR, "Can't allocate send buffer for starttls msg");

			instance->disconnect_reason =
			    QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;

			send_buffer_list_discard_new(&instance->send_buffer_list, send_buffer);
			return (-1);
		}

		send_buffer_list_put(&instance->send_buffer_list, send_buffer);

		instance->state = QDEVICE_NET_INSTANCE_STATE_WAITING_STARTTLS_BEING_SENT;
	} else if (res == 0) {
		if (qdevice_net_send_init(instance) != 0) {
			instance->disconnect_reason =
			    QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;

			return (-1);
		}
	}

	return (0);
}