/******************************************************************************
 *                                                                            *
 * Function: process_configuration_sync                                       *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_configuration_sync()
{
	const char	*__function_name = "process_configuration_sync";

	zbx_sock_t	sock;
	char		*data;
	struct		zbx_json_parse jp;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	connect_to_server(&sock, 600, CONFIG_PROXYCONFIG_RETRY); /* retry till have a connection */

	if (FAIL == get_data_from_server(&sock, ZBX_PROTO_VALUE_PROXY_CONFIG, &data))
		goto exit;

	if ('\0' != *data)
		zabbix_log(LOG_LEVEL_WARNING, "Received configuration data from server. Datalen " ZBX_FS_SIZE_T,
				(zbx_fs_size_t)strlen(data));
	else
		zabbix_log(LOG_LEVEL_WARNING, "Cannot obtain configuration data from server. "
				"Proxy host name might not be matching that on the server.");

	if (FAIL == zbx_json_open(data, &jp))
		goto exit;

	process_proxyconfig(&jp);
exit:
	disconnect_server(&sock);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Пример #2
0
/******************************************************************************
 *                                                                            *
 * Function: put_data_to_server                                               *
 *                                                                            *
 * Purpose: send data from server                                             *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - processed succesfully                              * 
 *               FAIL - an error occured                                      *
 *                                                                            *
 * Author: Alksander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	put_data_to_server(zbx_sock_t *sock, struct zbx_json *j)
{
	struct zbx_json_parse	jp;
	int			ret = FAIL;
	char			*answer, value[MAX_STRING_LEN];

	zabbix_log(LOG_LEVEL_DEBUG, "In put_data_to_server() [datalen:%zd]",
			j->buffer_size);

	if (FAIL == send_data_to_server(sock, j->buffer))
		goto exit;

	if (FAIL == recv_data_from_server(sock, &answer))
		goto exit;

	if (FAIL == zbx_json_open(answer, &jp))
		goto exit;

	if (FAIL == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value)))
		goto exit;

	if (0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS))
		goto exit;

	ret = SUCCEED;
exit:
	zabbix_log(LOG_LEVEL_DEBUG, "End of put_data_to_server():%s",
			zbx_result_string(ret));

	return ret;
}
Пример #3
0
/******************************************************************************
 *                                                                            *
 * Function: check_response                                                   *
 *                                                                            *
 * Purpose: Check whether JSON response is SUCCEED                            *
 *                                                                            *
 * Parameters: JSON response from Zabbix trapper                              *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: zabbix_sender has almost the same function!                      *
 *                                                                            *
 ******************************************************************************/
static int	check_response(char *response)
{
	const char		*__function_name = "check_response";

	struct zbx_json_parse	jp;
	char			value[MAX_STRING_LEN];
	char			info[MAX_STRING_LEN];
	int			ret = SUCCEED;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() response:'%s'", __function_name, response);

	ret = zbx_json_open(response, &jp);

	if (SUCCEED == ret)
		ret = zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value));

	if (SUCCEED == ret && 0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS))
		ret = FAIL;

	if (SUCCEED == ret && SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, info, sizeof(info)))
		zabbix_log(LOG_LEVEL_DEBUG, "info from server: '%s'", info);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #4
0
/******************************************************************************
 *                                                                            *
 * Function:                                                                  *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int process_jatrap(zbx_sock_t * sock, char *s)
{
    int ret = SUCCEED;
    struct zbx_json_parse jp;
    char value[MAX_STRING_LEN];
    char *message = NULL;
    static JOBARG_JOBNET_INFO ji;
    zbx_rtrim(s, " \r\n");
    zabbix_log(LOG_LEVEL_DEBUG, "Jatrapper got [%s] len %zd", s,
               strlen(s));

    /*JSON Format check */
    if (SUCCEED != zbx_json_open(s, &jp)) {
        ja_log("JATRAPPER200037", 0, NULL, 0);
        message =
            zbx_dsprintf(message,
                         "Received message error: [JSON format error]");
        ret = FAIL;
        reply_jobresult_response(sock, ret, message);
        zbx_free(message);
        return ret;
    }

    /*[kind] check */
    if (SUCCEED !=
        zbx_json_value_by_name(&jp, JA_PROTO_TAG_KIND, value,
                               sizeof(value))) {
        ja_log("JATRAPPER200036", 0, NULL, 0);
        message =
            zbx_dsprintf(message,
                         "Received message error: [kind] not found");
        ret = FAIL;
        reply_jobresult_response(sock, ret, message);
        zbx_free(message);
        return ret;
    }
    if (0 == strcmp(value, JA_PROTO_VALUE_JOBRESULT)) {
        /*from Job agent */
    } else if (0 == strcmp(value, JA_PROTO_VALUE_JOBNETRUN)) {
        /*from external I/F */
        message = evaluate_jobnetrun(sock, &jp, &ret);
        reply_jobnetrun_response(sock, ret, message);
    } else if (0 == strcmp(value, JA_PROTO_VALUE_JOBNETSTATUSRQ)) {
        /*from jobnet-status request */
        init_jobnetinfo(&ji);
        message = evaluate_jobnetstatusrq(sock, &jp, &ret, &ji);
        reply_jobnetstatusrq_response(sock, ret, &ji, message);
    } else {
        ja_log("JATRAPPER200035", 0, NULL, 0);
        message =
            zbx_dsprintf(message,
                         "Received message error: [kind] is not correct.");
        ret = FAIL;
        reply_jobresult_response(sock, ret, message);
    }
    zbx_free(message);
    return ret;
}
Пример #5
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_recv_response                                                *
 *                                                                            *
 * Purpose: read a response message (in JSON format) from socket, optionally  *
 *          extract "info" value.                                             *
 *                                                                            *
 * Parameters: sock    - [IN] socket descriptor                               *
 *             timeout - [IN] timeout for this operation                      *
 *             error   - [OUT] pointer to error message                       *
 *                                                                            *
 * Return value: SUCCEED - "response":"success" successfully retrieved        *
 *               FAIL    - otherwise                                          *
 * Comments:                                                                  *
 *     Allocates memory.                                                      *
 *                                                                            *
 *     If an error occurs, the function allocates dynamic memory for an error *
 *     message and writes its address into location pointed to by "error"     *
 *     parameter.                                                             *
 *                                                                            *
 *     When the "info" value is present in the response message then function *
 *     copies the "info" value into the "error" buffer as additional          *
 *     information                                                            *
 *                                                                            *
 *     IMPORTANT: it is a responsibility of the caller to release the         *
 *                "error" memory !                                            *
 *                                                                            *
 ******************************************************************************/
int	zbx_recv_response(zbx_socket_t *sock, int timeout, char **error)
{
	const char		*__function_name = "zbx_recv_response";

	struct zbx_json_parse	jp;
	char			value[16];
	int			ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (SUCCEED != zbx_tcp_recv_to(sock, timeout))
	{
		/* since we have successfully sent data earlier, we assume the other */
		/* side is just too busy processing our data if there is no response */
		*error = zbx_strdup(*error, zbx_socket_strerror());
		goto out;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s() '%s'", __function_name, sock->buffer);

	/* deal with empty string here because zbx_json_open() does not produce an error message in this case */
	if ('\0' == *sock->buffer)
	{
		*error = zbx_strdup(*error, "empty string received");
		goto out;
	}

	if (SUCCEED != zbx_json_open(sock->buffer, &jp))
	{
		*error = zbx_strdup(*error, zbx_json_strerror());
		goto out;
	}

	if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value)))
	{
		*error = zbx_strdup(*error, "no \"" ZBX_PROTO_TAG_RESPONSE "\" tag");
		goto out;
	}

	if (0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS))
	{
		char	*info = NULL;
		size_t	info_alloc = 0;

		if (SUCCEED == zbx_json_value_by_name_dyn(&jp, ZBX_PROTO_TAG_INFO, &info, &info_alloc))
			*error = zbx_strdup(*error, info);
		else
			*error = zbx_dsprintf(*error, "negative response \"%s\"", value);
		zbx_free(info);
		goto out;
	}

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #6
0
static int	lld_rows_get(char *value, lld_filter_t *filter, zbx_vector_ptr_t *lld_rows, char **error)
{
	const char		*__function_name = "lld_rows_get";

	struct zbx_json_parse	jp, jp_data, jp_row;
	const char		*p;
	zbx_lld_row_t		*lld_row;
	int			ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (SUCCEED != zbx_json_open(value, &jp))
	{
		*error = zbx_strdup(*error, "Value should be a JSON object.");
		goto out;
	}

	/* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */
	/*         ^-------------------------------------------^  */
	if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
	{
		*error = zbx_dsprintf(*error, "Cannot find the \"%s\" array in the received JSON object.",
				ZBX_PROTO_TAG_DATA);
		goto out;
	}

	p = NULL;
	/* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */
	/*          ^                                             */
	while (NULL != (p = zbx_json_next(&jp_data, p)))
	{
		/* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */
		/*          ^------------------^                          */
		if (FAIL == zbx_json_brackets_open(p, &jp_row))
			continue;

		if (SUCCEED != filter_evaluate(filter, &jp_row))
			continue;

		lld_row = zbx_malloc(NULL, sizeof(zbx_lld_row_t));
		lld_row->jp_row = jp_row;
		zbx_vector_ptr_create(&lld_row->item_links);

		zbx_vector_ptr_append(lld_rows, lld_row);
	}

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #7
0
/******************************************************************************
 *                                                                            *
 * Function: check_response                                                   *
 *                                                                            *
 * Purpose: Check whether JSON response is SUCCEED                            *
 *                                                                            *
 * Parameters: result SUCCEED or FAIL                                         *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: active agent has almost the same function!                       *
 *                                                                            *
 ******************************************************************************/
static int	check_response(char *response)
{
	struct zbx_json_parse	jp;
	char			value[MAX_STRING_LEN];
	char			info[MAX_STRING_LEN];
	int			ret;

	ret = zbx_json_open(response, &jp);

	if (SUCCEED == ret)
		ret = zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value));

	if (SUCCEED == ret && 0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS))
		ret = FAIL;

	if (SUCCEED == ret && SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, info, sizeof(info)))
		printf("info from server: \"%s\"\n", info);

	return ret;
}
Пример #8
0
/******************************************************************************
 *                                                                            *
 * Function: check_response                                                   *
 *                                                                            *
 * Purpose: Check if json response is SUCCEED                                 *
 *                                                                            *
 * Parameters: result SUCCEED or FAIL                                         *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occured                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: zabbix_sender has exactly the same function!                     *
 *                                                                            *
 ******************************************************************************/
static int	check_response(char *response)
{
	struct 		zbx_json_parse jp;
	char		value[MAX_STRING_LEN];
	char		info[MAX_STRING_LEN];

	int	ret = SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In check_response(%s)", response);

	ret = zbx_json_open(response, &jp);

	if (SUCCEED == ret)
	{
		ret = zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE,value, sizeof(value));
	}

	if(SUCCEED == ret)
	{
		if(strcmp(value, ZBX_PROTO_VALUE_SUCCESS) != 0)
		{
			ret = FAIL;
		}
	}

	if (SUCCEED == ret)
	{
		if(SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, info, sizeof(info)))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Info from server: %s",
				info);
		}
	}

	return ret;
}
Пример #9
0
/******************************************************************************
 *                                                                            *
 * Function: parse_list_of_checks                                             *
 *                                                                            *
 * Purpose: Parse list of active checks received from server                  *
 *                                                                            *
 * Parameters: str - NULL terminated string received from server              *
 *                                                                            *
 * Return value: returns SUCCEED on succesfull parsing,                       *
 *               FAIL on an incoorrect format of string                       *
 *                                                                            *
 * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol)             *
 *                                                                            *
 * Comments:                                                                  *
 *    String reprents as "ZBX_EOF" termination list                           *
 *    With '\n' delimeter between elements.                                   *
 *    Each element represents as:                                             *
 *           <key>:<refresh time>:<last log size>                             *
 *                                                                            *
 ******************************************************************************/
static int	parse_list_of_checks(char *str)
{
	const char		*p;
	char			name[MAX_STRING_LEN], key_orig[MAX_STRING_LEN], expression[MAX_STRING_LEN], tmp[MAX_STRING_LEN],
				exp_delimiter;
	int			delay, lastlogsize, expression_type, case_sensitive;
	struct zbx_json_parse	jp;
	struct zbx_json_parse	jp_data, jp_row;

	zabbix_log(LOG_LEVEL_DEBUG, "In parse_list_of_checks()");

	disable_all_metrics();

	if (SUCCEED != zbx_json_open(str, &jp))
		goto json_error;

	if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, tmp, sizeof(tmp)))
		goto json_error;

	if (0 != strcmp(tmp, ZBX_PROTO_VALUE_SUCCESS))
	{
		zabbix_log(LOG_LEVEL_ERR, "Unsucesfull response received from server");
		return FAIL;
	}

	if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
		goto json_error;

 	p = NULL;
	while (NULL != (p = zbx_json_next(&jp_data, p)))
	{
/* {"data":[{"key":"system.cpu.num",...,...},{...},...]} 
 *          ^------------------------------^
 */ 		if (SUCCEED != zbx_json_brackets_open(p, &jp_row))
			goto json_error;

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, name, sizeof(name)) || *name == '\0')
		{
			zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
					ZBX_PROTO_TAG_KEY);
			continue;
		}

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY_ORIG, key_orig, sizeof(key_orig)) || *key_orig == '\0')
			zbx_strlcpy(key_orig, name, sizeof(key_orig));

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_DELAY, tmp, sizeof(tmp)) || *tmp == '\0')
		{
			zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
					ZBX_PROTO_TAG_DELAY);
			continue;
		}

		delay = atoi(tmp);

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp)) || *tmp == '\0')
		{
			zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
					ZBX_PROTO_TAG_LOGLASTSIZE);
			continue;
		}

		lastlogsize = atoi(tmp);

		add_check(name, key_orig, delay, lastlogsize);
	}

	clean_regexps_ex(regexps, &regexps_num);

	if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_REGEXP, &jp_data))
	{
	 	p = NULL;
		while (NULL != (p = zbx_json_next(&jp_data, p)))
		{
/* {"regexp":[{"name":"regexp1",...,...},{...},...]} 
 *            ^------------------------^
 */			if (SUCCEED != zbx_json_brackets_open(p, &jp_row))
				goto json_error;

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "name", name, sizeof(name)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
						"name");
				continue;
			}

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression", expression, sizeof(expression)) || *expression == '\0')
			{
				zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
						"expression");
				continue;
			}

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression_type", tmp, sizeof(tmp)) || *tmp == '\0')
			{
				zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
						"expression_type");
				continue;
			}

			expression_type = atoi(tmp);

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "exp_delimiter", tmp, sizeof(tmp)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
						"exp_delimiter");
				continue;
			}

			exp_delimiter = tmp[0];

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "case_sensitive", tmp, sizeof(tmp)) || *tmp == '\0')
			{
				zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"",
						"case_sensitive");
				continue;
			}

			case_sensitive = atoi(tmp);

			add_regexp_ex(&regexps, &regexps_alloc, &regexps_num,
					name, expression, expression_type, exp_delimiter, case_sensitive);
		}
	}

	return SUCCEED;
json_error:
	zabbix_log(LOG_LEVEL_ERR, "Can't parse list of active checks. %s",
			zbx_json_strerror());
	return FAIL;
}
Пример #10
0
static int	process_trap(zbx_sock_t	*sock, char *s, int max_len)
{
	char	*pl, *pr, *data, value_dec[MAX_BUFFER_LEN];
	char	lastlogsize[11], timestamp[11], source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11];
	int	sender_nodeid, nodeid;
	char	*answer;

	int	ret = SUCCEED, res;
	size_t	datalen;

	struct 		zbx_json_parse jp;
	char		value[MAX_STRING_LEN];
	AGENT_VALUE	av;

	memset(&av, 0, sizeof(AGENT_VALUE));

	zbx_rtrim(s, " \r\n");

	datalen = strlen(s);
	zabbix_log(LOG_LEVEL_DEBUG, "Trapper got [%s] len " ZBX_FS_SIZE_T, s, (zbx_fs_size_t)datalen);

	if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21))	/* Request for list of active checks */
	{
		ret = send_list_of_active_checks(sock, s);
	}
	else if (strncmp(s, "ZBX_GET_HISTORY_LAST_ID", 23) == 0) /* Request for last ids */
	{
		send_history_last_id(sock, s);
		return ret;
	}
	else	/* Process information sent by zabbix_sender */
	{
		/* Node data exchange? */
		if (strncmp(s, "Data", 4) == 0)
		{
			node_sync_lock(0);

			res = node_sync(s, &sender_nodeid, &nodeid);
			if (FAIL == res)
			{
				alarm(CONFIG_TIMEOUT);
				send_data_to_node(sender_nodeid, sock, "FAIL");
				alarm(0);
			}
			else
			{
				res = calculate_checksums(nodeid, NULL, 0);
				if (SUCCEED == res && NULL != (data = get_config_data(nodeid, ZBX_NODE_SLAVE)))
				{
					zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Sending configuration changes"
							" to slave node %d for node %d datalen " ZBX_FS_SIZE_T,
							CONFIG_NODEID,
							sender_nodeid,
							nodeid,
							(zbx_fs_size_t)strlen(data));
					alarm(CONFIG_TRAPPER_TIMEOUT);
					res = send_data_to_node(sender_nodeid, sock, data);
					zbx_free(data);
					if (SUCCEED == res)
						res = recv_data_from_node(sender_nodeid, sock, &answer);
					if (SUCCEED == res && 0 == strcmp(answer, "OK"))
						res = update_checksums(nodeid, ZBX_NODE_SLAVE, SUCCEED, NULL, 0, NULL);
					alarm(0);
				}
			}

			node_sync_unlock(0);

			return ret;
		}
		/* Slave node history ? */
		if (strncmp(s, "History", 7) == 0)
		{
			const char	*reply;

			reply = (SUCCEED == node_history(s, datalen) ? "OK" : "FAIL");

			alarm(CONFIG_TIMEOUT);
			if (SUCCEED != zbx_tcp_send_raw(sock, reply))
			{
				zabbix_log(LOG_LEVEL_WARNING, "Error sending %s to node", reply);
				zabbix_syslog("Trapper: error sending %s to node", reply);
			}
			alarm(0);

			return ret;
		}
		/* JSON protocol? */
		else if (SUCCEED == zbx_json_open(s, &jp))
		{
			if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value)))
			{
				if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG))
				{
					if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
						send_proxyconfig(sock, &jp);
					else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
					{
						zabbix_log(LOG_LEVEL_WARNING, "Received configuration data from server."
								" Datalen " ZBX_FS_SIZE_T, (zbx_fs_size_t)datalen);
						recv_proxyconfig(sock, &jp);
					}
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) ||
					0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
				{
					recv_agenthistory(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA))
				{
					if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
						recv_proxyhistory(sock, &jp);
					else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
						send_proxyhistory(sock);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA))
				{
					if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
						recv_discovery_data(sock, &jp);
					else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
						send_discovery_data(sock);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA))
				{
					if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
						recv_areg_data(sock, &jp);
					else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
						send_areg_data(sock);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT))
				{
					if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
						recv_proxy_heartbeat(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
				{
					ret = send_list_of_active_checks_json(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_HOST_AVAILABILITY))
				{
					if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER))
						recv_host_availability(sock, &jp);
					else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
						send_host_availability(sock);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND))
				{
					ret = node_process_command(sock, s, &jp);
				}
				else
				{
					zabbix_log(LOG_LEVEL_WARNING, "Unknown request received [%s]",
							value);
				}
			}
			return ret;
		}
		/* XML protocol? */
		else if (*s == '<')
		{
			comms_parse_response(s, av.host_name, sizeof(av.host_name), av.key, sizeof(av.key), value_dec, sizeof(value_dec),
					lastlogsize, sizeof(lastlogsize), timestamp, sizeof(timestamp),
					source, sizeof(source),	severity, sizeof(severity));

			av.value	= value_dec;
			av.lastlogsize	= atoi(lastlogsize);
			av.timestamp	= atoi(timestamp);
			av.source	= source;
			av.severity	= atoi(severity);
		}
		else
		{
			pl = s;
			if (NULL == (pr = strchr(pl, ':')))
				return FAIL;

			*pr = '\0';
			zbx_strlcpy(av.host_name, pl, sizeof(av.host_name));
			*pr = ':';

			pl = pr + 1;
			if (NULL == (pr = strchr(pl, ':')))
				return FAIL;

			*pr = '\0';
			zbx_strlcpy(av.key, pl, sizeof(av.key));
			*pr = ':';

			av.value	= pr + 1;
			av.severity	= 0;
		}

		av.clock = time(NULL);

		process_mass_data(sock, 0, &av, 1, NULL);

		alarm(CONFIG_TIMEOUT);
		if (SUCCEED != zbx_tcp_send_raw(sock, SUCCEED == ret ? "OK" : "NOT OK"))
		{
			zabbix_log(LOG_LEVEL_WARNING, "Error sending result back");
			zabbix_syslog("Trapper: error sending result back");
		}
		alarm(0);
	}
	return ret;
}
Пример #11
0
static int	lld_rows_get(char *value, char *filter, zbx_vector_ptr_t *lld_rows, char **error)
{
	const char		*__function_name = "lld_rows_get";

	struct zbx_json_parse	jp, jp_data, jp_row;
	char			*f_macro = NULL, *f_regexp = NULL;
	const char		*p;
	zbx_vector_ptr_t	regexps;
	zbx_lld_row_t		*lld_row;
	int			ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (SUCCEED != zbx_json_open(value, &jp))
	{
		*error = zbx_strdup(*error, "Value should be a JSON object.");
		goto out;
	}

	/* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */
	/*         ^-------------------------------------------^  */
	if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
	{
		*error = zbx_dsprintf(*error, "Cannot find the \"%s\" array in the received JSON object.",
				ZBX_PROTO_TAG_DATA);
		goto out;
	}

	zbx_vector_ptr_create(&regexps);

	if (NULL != (f_regexp = strchr(filter, ':')))
	{
		f_macro = filter;
		*f_regexp++ = '\0';

		if ('@' == *f_regexp)
			DCget_expressions_by_name(&regexps, f_regexp + 1);

		zabbix_log(LOG_LEVEL_DEBUG, "%s() f_macro:'%s' f_regexp:'%s'", __function_name, f_macro, f_regexp);
	}

	p = NULL;
	/* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */
	/*          ^                                             */
	while (NULL != (p = zbx_json_next(&jp_data, p)))
	{
		/* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */
		/*          ^------------------^                          */
		if (FAIL == zbx_json_brackets_open(p, &jp_row))
			continue;

		if (NULL != f_macro && SUCCEED != lld_check_record(&jp_row, f_macro, f_regexp, &regexps))
			continue;

		lld_row = zbx_malloc(NULL, sizeof(zbx_lld_row_t));
		memcpy(&lld_row->jp_row, &jp_row, sizeof(struct zbx_json_parse));
		zbx_vector_ptr_create(&lld_row->item_links);

		zbx_vector_ptr_append(lld_rows, lld_row);
	}

	zbx_regexp_clean_expressions(&regexps);
	zbx_vector_ptr_destroy(&regexps);

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #12
0
static int	parse_response(DC_ITEM *items, AGENT_RESULT *results, int *errcodes, int num,
		char *response, char *error, int max_error_len)
{
	const char		*p;
	struct zbx_json_parse	jp, jp_data, jp_row;
	char			*value = NULL;
	size_t			value_alloc = 0;
	int			i, ret = GATEWAY_ERROR;

	if (SUCCEED == zbx_json_open(response, &jp))
	{
		if (SUCCEED != zbx_json_value_by_name_dyn(&jp, ZBX_PROTO_TAG_RESPONSE, &value, &value_alloc))
		{
			zbx_snprintf(error, max_error_len, "No '%s' tag in received JSON", ZBX_PROTO_TAG_RESPONSE);
			goto exit;
		}

		if (0 == strcmp(value, ZBX_PROTO_VALUE_SUCCESS))
		{
			if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
			{
				zbx_strlcpy(error, "Cannot open data array in received JSON", max_error_len);
				goto exit;
			}

			p = NULL;

			for (i = 0; i < num; i++)
			{
				if (SUCCEED != errcodes[i])
					continue;

				if (NULL == (p = zbx_json_next(&jp_data, p)))
				{
					zbx_strlcpy(error, "Not all values included in received JSON", max_error_len);
					goto exit;
				}

				if (SUCCEED != zbx_json_brackets_open(p, &jp_row))
				{
					zbx_strlcpy(error, "Cannot open value object in received JSON", max_error_len);
					goto exit;
				}

				if (SUCCEED == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_VALUE, &value, &value_alloc))
				{
					if (SUCCEED == set_result_type(&results[i],
								items[i].value_type, items[i].data_type, value))
						errcodes[i] = SUCCEED;
					else
						errcodes[i] = NOTSUPPORTED;
				}
				else if (SUCCEED == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_ERROR, &value, &value_alloc))
				{
					SET_MSG_RESULT(&results[i], zbx_strdup(NULL, value));
					errcodes[i] = NOTSUPPORTED;
				}
				else
				{
					SET_MSG_RESULT(&results[i], zbx_strdup(NULL, "Cannot get item value or error message"));
					errcodes[i] = AGENT_ERROR;
				}
			}

			ret = SUCCEED;
		}
		else if (0 == strcmp(value, ZBX_PROTO_VALUE_FAILED))
		{
			if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_ERROR, error, max_error_len))
				ret = NETWORK_ERROR;
			else
				zbx_strlcpy(error, "Cannot get error message describing reasons for failure", max_error_len);

			goto exit;
		}
		else
		{
			zbx_snprintf(error, max_error_len, "Bad '%s' tag value '%s' in received JSON",
					ZBX_PROTO_TAG_RESPONSE, value);
			goto exit;
		}
	}
	else
	{
		zbx_strlcpy(error, "Cannot open received JSON", max_error_len);
		goto exit;
	}
exit:
	zbx_free(value);

	return ret;
}
Пример #13
0
static int	process_trap(zbx_sock_t	*sock, char *s, int max_len)
{
	char	*server,*key,*value_string, *data;
	char	copy[MAX_STRING_LEN];
	char	host_dec[MAX_STRING_LEN],key_dec[MAX_STRING_LEN],value_dec[MAX_STRING_LEN];
	char	lastlogsize[MAX_STRING_LEN];
	char	timestamp[MAX_STRING_LEN];
	char	source[MAX_STRING_LEN];
	char	severity[MAX_STRING_LEN];
	int	sender_nodeid, nodeid;
	char	*answer;

	int	ret=SUCCEED, res;
	size_t	datalen;

	struct 		zbx_json_parse jp;
	char		value[MAX_STRING_LEN];
	AGENT_VALUE	av;

	zbx_rtrim(s, " \r\n\0");

	datalen = strlen(s);
	zabbix_log( LOG_LEVEL_DEBUG, "Trapper got [%s] len %zd",
		s,
		datalen);

	if (0 == strncmp(s,"ZBX_GET_ACTIVE_CHECKS", 21))	/* Request for list of active checks */
	{
		ret = send_list_of_active_checks(sock, s);
/* Request for last ids */
	} else if (strncmp(s,"ZBX_GET_HISTORY_LAST_ID", 23) == 0) {
		send_history_last_id(sock, s);
		return ret;
	} else if (strncmp(s,"ZBX_GET_TRENDS_LAST_ID", 22) == 0) {
		send_trends_last_id(sock, s);
		return ret;
/* Process information sent by zabbix_sender */
	} else {
		/* Command? */
		if(strncmp(s,"Command",7) == 0)
		{
			node_process_command(sock, s);
			return ret;
		}
		/* Node data exchange? */
		if(strncmp(s,"Data",4) == 0)
		{
			node_sync_lock(0);

/*			zabbix_log( LOG_LEVEL_WARNING, "Node data received [len:%d]", strlen(s)); */
			res = node_sync(s, &sender_nodeid, &nodeid);
			if (FAIL == res)
				send_data_to_node(sender_nodeid, sock, "FAIL");
			else {
				res = calculate_checksums(nodeid, NULL, 0);
				if (SUCCEED == res && NULL != (data = get_config_data(nodeid, ZBX_NODE_SLAVE))) {
					res = send_data_to_node(sender_nodeid, sock, data);
					zbx_free(data);
					if (SUCCEED == res)
						res = recv_data_from_node(sender_nodeid, sock, &answer);
					if (SUCCEED == res && 0 == strcmp(answer, "OK"))
						res = update_checksums(nodeid, ZBX_NODE_SLAVE, SUCCEED, NULL, 0, NULL);
				}
			}

			node_sync_unlock(0);

			return ret;
		}
		/* Slave node history ? */
		if(strncmp(s,"History",7) == 0)
		{
/*			zabbix_log( LOG_LEVEL_WARNING, "Slave node history received [len:%d]", strlen(s)); */
			if (node_history(s, datalen) == SUCCEED) {
				if (zbx_tcp_send_raw(sock,"OK") != SUCCEED) {
					zabbix_log( LOG_LEVEL_WARNING, "Error sending confirmation to node");
					zabbix_syslog("Trapper: error sending confirmation to node");
				}
			}
			return ret;
		}
		/* JSON protocol? */
		else if (SUCCEED == zbx_json_open(s, &jp))
		{
			if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value))) {
				if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG) && zbx_process == ZBX_PROCESS_SERVER)
				{
					send_proxyconfig(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) ||
					0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
				{
					ret = process_new_values(sock, &jp, 0);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA) && zbx_process == ZBX_PROCESS_SERVER)
				{
					ret = process_proxy_values(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA) && zbx_process == ZBX_PROCESS_SERVER)
				{
					ret = process_discovery_data(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT) && zbx_process == ZBX_PROCESS_SERVER)
				{
					ret = process_proxy_heartbeat(sock, &jp);
				}
				else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
				{
					ret = send_list_of_active_checks_json(sock, &jp);
				}
				else
				{
					zabbix_log( LOG_LEVEL_WARNING, "Unknown request received [%s]",
						value);
				}
			}
			return ret;
		}
		/* New XML protocol? */
		else if(s[0]=='<')
		{
			zabbix_log( LOG_LEVEL_DEBUG, "XML received [%s]", s);

			comms_parse_response(s,host_dec,key_dec,value_dec,lastlogsize,timestamp,source,severity,sizeof(host_dec)-1);

			server=host_dec;
			value_string=value_dec;
			key=key_dec;
		}
		else
		{
			strscpy(copy,s);

			server=(char *)strtok(s,":");
			if(NULL == server)
			{
				return FAIL;
			}

			key=(char *)strtok(NULL,":");
			if(NULL == key)
			{
				return FAIL;
			}
	
			value_string=strchr(copy,':');
			value_string=strchr(value_string+1,':');

			if(NULL == value_string)
			{
				return FAIL;
			}
			/* It points to ':', so have to increment */
			value_string++;
			lastlogsize[0]=0;
			timestamp[0]=0;
			source[0]=0;
			severity[0]=0;
		}
		zabbix_log( LOG_LEVEL_DEBUG, "Value [%s]", value_string);

		av.clock = time(NULL);
		zbx_strlcpy(av.host_name, server, sizeof(av.host_name));
		zbx_strlcpy(av.key, key, sizeof(av.key));
		av.value = value_string;
		av.lastlogsize = atoi(lastlogsize);
		av.timestamp = atoi(timestamp);
		av.source = source;
		av.severity = atoi(severity);

		process_mass_data(sock, 0, &av, 1, NULL, 0);

		if( zbx_tcp_send_raw(sock, SUCCEED == ret ? "OK" : "NOT OK") != SUCCEED)
		{
			zabbix_log( LOG_LEVEL_WARNING, "Error sending result back");
			zabbix_syslog("Trapper: error sending result back");
		}
		zabbix_log( LOG_LEVEL_DEBUG, "After write()");
	}	
	return ret;
}
Пример #14
0
/******************************************************************************
 *                                                                            *
 * Function: parse_list_of_checks                                             *
 *                                                                            *
 * Purpose: Parse list of active checks received from server                  *
 *                                                                            *
 * Parameters: str  - NULL terminated string received from server             *
 *             host - address of host                                         *
 *             port - port number on host                                     *
 *                                                                            *
 * Return value: returns SUCCEED on successful parsing,                       *
 *               FAIL on an incorrect format of string                        *
 *                                                                            *
 * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol)             *
 *                                                                            *
 * Comments:                                                                  *
 *    String represented as "ZBX_EOF" termination list                        *
 *    With '\n' delimiter between elements.                                   *
 *    Each element represented as:                                            *
 *           <key>:<refresh time>:<last log size>:<modification time>         *
 *                                                                            *
 ******************************************************************************/
static int	parse_list_of_checks(char *str, const char *host, unsigned short port)
{
	const char		*p;
	char			name[MAX_STRING_LEN], key_orig[MAX_STRING_LEN], expression[MAX_STRING_LEN],
				tmp[MAX_STRING_LEN], exp_delimiter;
	int			delay, mtime, expression_type, case_sensitive;
	zbx_uint64_t		lastlogsize;
	struct zbx_json_parse	jp;
	struct zbx_json_parse	jp_data, jp_row;

	zabbix_log(LOG_LEVEL_DEBUG, "In parse_list_of_checks()");

	disable_all_metrics();

	if (SUCCEED != zbx_json_open(str, &jp))
		goto json_error;

	if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, tmp, sizeof(tmp)))
		goto json_error;

	if (0 != strcmp(tmp, ZBX_PROTO_VALUE_SUCCESS))
	{
		if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, tmp, sizeof(tmp)))
			zabbix_log(LOG_LEVEL_WARNING, "no active checks on server [%s:%hu]: %s", host, port, tmp);
		else
			zabbix_log(LOG_LEVEL_WARNING, "no active checks on server");
		return FAIL;
	}

	if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
		goto json_error;

 	p = NULL;
	while (NULL != (p = zbx_json_next(&jp_data, p)))
	{
/* {"data":[{"key":"system.cpu.num",...,...},{...},...]}
 *          ^------------------------------^
 */ 		if (SUCCEED != zbx_json_brackets_open(p, &jp_row))
			goto json_error;

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, name, sizeof(name)) || '\0' == *name)
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_KEY);
			continue;
		}

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY_ORIG, key_orig, sizeof(key_orig))
				|| '\0' == *key_orig) {
			zbx_strlcpy(key_orig, name, sizeof(key_orig));
		}

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_DELAY, tmp, sizeof(tmp)) || '\0' == *tmp)
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_DELAY);
			continue;
		}

		delay = atoi(tmp);

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp)) ||
				SUCCEED != is_uint64(tmp, &lastlogsize))
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_LOGLASTSIZE);
			continue;
		}

		if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_MTIME, tmp, sizeof(tmp)) || '\0' == *tmp)
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_MTIME);
			mtime = 0;
		}
		else
			mtime = atoi(tmp);

		add_check(name, key_orig, delay, lastlogsize, mtime);
	}

	zbx_regexp_clean_expressions(&regexps);

	if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_REGEXP, &jp_data))
	{
	 	p = NULL;
		while (NULL != (p = zbx_json_next(&jp_data, p)))
		{
/* {"regexp":[{"name":"regexp1",...,...},{...},...]}
 *            ^------------------------^
 */			if (SUCCEED != zbx_json_brackets_open(p, &jp_row))
				goto json_error;

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "name", name, sizeof(name)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "name");
				continue;
			}

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression", expression, sizeof(expression)) ||
					'\0' == *expression)
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "expression");
				continue;
			}

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression_type", tmp, sizeof(tmp)) ||
					'\0' == *tmp)
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "expression_type");
				continue;
			}

			expression_type = atoi(tmp);

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "exp_delimiter", tmp, sizeof(tmp)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "exp_delimiter");
				continue;
			}

			exp_delimiter = tmp[0];

			if (SUCCEED != zbx_json_value_by_name(&jp_row, "case_sensitive", tmp,
					sizeof(tmp)) || '\0' == *tmp)
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "case_sensitive");
				continue;
			}

			case_sensitive = atoi(tmp);

			add_regexp_ex(&regexps, name, expression, expression_type, exp_delimiter, case_sensitive);
		}
	}

	return SUCCEED;
json_error:
	zabbix_log(LOG_LEVEL_ERR, "cannot parse list of active checks: %s", zbx_json_strerror());

	return FAIL;
}
Пример #15
0
static int	process_trap(zbx_socket_t *sock, char *s, zbx_timespec_t *ts)
{
	int	ret = SUCCEED;

	zbx_rtrim(s, " \r\n");

	zabbix_log(LOG_LEVEL_DEBUG, "trapper got '%s'", s);

	if ('{' == *s)	/* JSON protocol */
	{
		struct zbx_json_parse	jp;
		char			value[MAX_STRING_LEN];

		if (SUCCEED != zbx_json_open(s, &jp))
		{
			zbx_send_response(sock, FAIL, zbx_json_strerror(), CONFIG_TIMEOUT);
			zabbix_log(LOG_LEVEL_WARNING, "received invalid JSON object from %s: %s",
					sock->peer, zbx_json_strerror());
			return FAIL;
		}

		if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value)))
		{
			if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
				{
					send_proxyconfig(sock, &jp);
				}
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
				{
					zabbix_log(LOG_LEVEL_WARNING, "received configuration data from server"
							" at \"%s\", datalen " ZBX_FS_SIZE_T,
							sock->peer, (zbx_fs_size_t)(jp.end - jp.start + 1));
					recv_proxyconfig(sock, &jp);
				}
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_ACTIVE))
				{
					/* This is a misconfiguration: the proxy is configured in active mode */
					/* but server sends requests to it as to a proxy in passive mode. To  */
					/* prevent logging of this problem for every request we report it     */
					/* only when the server sends configuration to the proxy and ignore   */
					/* it for other requests.                                             */
					active_passive_misconfig(sock);
				}
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) ||
					0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
			{
				recv_agenthistory(sock, &jp, ts);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_proxyhistory(sock, &jp, ts);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_proxyhistory(sock, ts);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_discovery_data(sock, &jp);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_discovery_data(sock);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_areg_data(sock, &jp);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_areg_data(sock);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_proxy_heartbeat(sock, &jp);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
			{
				ret = send_list_of_active_checks_json(sock, &jp);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_HOST_AVAILABILITY))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_host_availability(sock, &jp);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_host_availability(sock);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND))
			{
				ret = node_process_command(sock, s, &jp);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_QUEUE))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					ret = recv_getqueue(sock, &jp);
			}
			else
				zabbix_log(LOG_LEVEL_WARNING, "unknown request received [%s]", value);
		}
	}
	else if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21))	/* request for list of active checks */
	{
		ret = send_list_of_active_checks(sock, s);
	}
	else
	{
		char		value_dec[MAX_BUFFER_LEN], lastlogsize[ZBX_MAX_UINT64_LEN], timestamp[11],
				source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11];
		AGENT_VALUE	av;

		memset(&av, 0, sizeof(AGENT_VALUE));

		if ('<' == *s)	/* XML protocol */
		{
			comms_parse_response(s, av.host_name, sizeof(av.host_name), av.key, sizeof(av.key), value_dec,
					sizeof(value_dec), lastlogsize, sizeof(lastlogsize), timestamp,
					sizeof(timestamp), source, sizeof(source), severity, sizeof(severity));

			av.value = value_dec;
			if (SUCCEED != is_uint64(lastlogsize, &av.lastlogsize))
				av.lastlogsize = 0;
			av.timestamp = atoi(timestamp);
			av.source = source;
			av.severity = atoi(severity);
		}
		else
		{
			char	*pl, *pr;

			pl = s;
			if (NULL == (pr = strchr(pl, ':')))
				return FAIL;

			*pr = '\0';
			zbx_strlcpy(av.host_name, pl, sizeof(av.host_name));
			*pr = ':';

			pl = pr + 1;
			if (NULL == (pr = strchr(pl, ':')))
				return FAIL;

			*pr = '\0';
			zbx_strlcpy(av.key, pl, sizeof(av.key));
			*pr = ':';

			av.value = pr + 1;
			av.severity = 0;
		}

		zbx_timespec(&av.ts);

		if (0 == strcmp(av.value, ZBX_NOTSUPPORTED))
			av.state = ITEM_STATE_NOTSUPPORTED;

		process_mass_data(sock, 0, &av, 1, NULL);

		zbx_alarm_on(CONFIG_TIMEOUT);
		if (SUCCEED != zbx_tcp_send_raw(sock, "OK"))
			zabbix_log(LOG_LEVEL_WARNING, "Error sending result back");
		zbx_alarm_off();
	}

	return ret;
}
Пример #16
0
/******************************************************************************
 *                                                                            *
 * Function: process_proxy                                                    *
 *                                                                            *
 * Purpose: retrieve values of metrics from monitored hosts                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	process_proxy(void)
{
	const char		*__function_name = "process_proxy";
	DC_PROXY		proxy;
	int			num, i, ret;
	struct zbx_json		j;
	struct zbx_json_parse	jp, jp_data;
	zbx_socket_t		s;
	char			*answer = NULL, *port = NULL;
	time_t			now;
	unsigned char		update_nextcheck;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (0 == (num = DCconfig_get_proxypoller_hosts(&proxy, 1)))
		goto exit;

	now = time(NULL);

	zbx_json_init(&j, 512 * 1024);

	for (i = 0; i < num; i++)
	{
		update_nextcheck = 0;

		if (proxy.proxy_config_nextcheck <= now)
			update_nextcheck |= 0x01;
		if (proxy.proxy_data_nextcheck <= now)
			update_nextcheck |= 0x02;

		proxy.addr = proxy.addr_orig;

		port = zbx_strdup(port, proxy.port_orig);
		substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
				&port, MACRO_TYPE_COMMON, NULL, 0);
		if (FAIL == is_ushort(port, &proxy.port))
		{
			zabbix_log(LOG_LEVEL_ERR, "invalid proxy \"%s\" port: \"%s\"", proxy.host, port);
			goto network_error;
		}

		if (proxy.proxy_config_nextcheck <= now)
		{
			char	*error = NULL;

			zbx_json_clean(&j);

			zbx_json_addstring(&j, ZBX_PROTO_TAG_REQUEST,
					ZBX_PROTO_VALUE_PROXY_CONFIG, ZBX_JSON_TYPE_STRING);
			zbx_json_addobject(&j, ZBX_PROTO_TAG_DATA);

			if (SUCCEED != (ret = get_proxyconfig_data(proxy.hostid, &j, &error)))
			{
				zabbix_log(LOG_LEVEL_ERR, "cannot collect configuration data for proxy \"%s\": %s",
						proxy.host, error);
				zbx_free(error);

				goto network_error;
			}

			if (SUCCEED == (ret = connect_to_proxy(&proxy, &s, CONFIG_TRAPPER_TIMEOUT)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\","
						" datalen " ZBX_FS_SIZE_T,
						proxy.host, get_ip_by_socket(&s), (zbx_fs_size_t)j.buffer_size);

				if (SUCCEED == (ret = send_data_to_proxy(&proxy, &s, j.buffer)))
				{
					char	*error = NULL;

					if (SUCCEED != (ret = zbx_recv_response(&s, 0, &error)))
					{
						zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration data to proxy"
								" \"%s\" at \"%s\": %s",
								proxy.host, get_ip_by_socket(&s), error);
					}
					zbx_free(error);
				}

				disconnect_proxy(&s);
			}

			if (SUCCEED != ret)
				goto network_error;
		}

		if (proxy.proxy_data_nextcheck <= now)
		{
			if (SUCCEED == get_data_from_proxy(&proxy,
					ZBX_PROTO_VALUE_HOST_AVAILABILITY, &answer))
			{
				if (SUCCEED == zbx_json_open(answer, &jp))
					process_host_availability(&jp);

				zbx_free(answer);
			}
			else
				goto network_error;
retry_history:
			if (SUCCEED == get_data_from_proxy(&proxy,
					ZBX_PROTO_VALUE_HISTORY_DATA, &answer))
			{
				if (SUCCEED == zbx_json_open(answer, &jp))
				{
					process_hist_data(NULL, &jp, proxy.hostid, NULL, 0);

					if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
					{
						if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data))
						{
							zbx_free(answer);
							goto retry_history;
						}
					}
				}
				zbx_free(answer);
			}
			else
				goto network_error;
retry_dhistory:
			if (SUCCEED == get_data_from_proxy(&proxy,
					ZBX_PROTO_VALUE_DISCOVERY_DATA, &answer))
			{
				if (SUCCEED == zbx_json_open(answer, &jp))
				{
					process_dhis_data(&jp);

					if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
					{
						if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data))
						{
							zbx_free(answer);
							goto retry_dhistory;
						}
					}
				}
				zbx_free(answer);
			}
			else
				goto network_error;
retry_autoreg_host:
			if (SUCCEED == get_data_from_proxy(&proxy,
					ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA, &answer))
			{
				if (SUCCEED == zbx_json_open(answer, &jp))
				{
					process_areg_data(&jp, proxy.hostid);

					if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data))
					{
						if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data))
						{
							zbx_free(answer);
							goto retry_autoreg_host;
						}
					}
				}
				zbx_free(answer);
			}
			else
				goto network_error;
		}

		DBbegin();
		update_proxy_lastaccess(proxy.hostid);
		DBcommit();
network_error:
		DCrequeue_proxy(proxy.hostid, update_nextcheck);
	}

	zbx_free(port);

	zbx_json_free(&j);
exit:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return num;
}