/****************************************************************************** * * * Function: recv_discovery_data * * * * Author: Alexander Vladishev * * * ******************************************************************************/ void recv_discovery_data(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_discovery_data"; int ret; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], *error = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != (ret = get_active_proxy_id(jp, &proxy_hostid, host, &error))) { zabbix_log(LOG_LEVEL_WARNING, "discovery data from active proxy on \"%s\" failed: %s", get_ip_by_socket(sock), error); goto out; } process_dhis_data(jp); out: zbx_send_response(sock, ret, error, CONFIG_TIMEOUT); zbx_free(error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); }
/****************************************************************************** * * * Function: send_proxyconfig * * * * Purpose: send configuration tables to the proxy from server * * (for active proxies) * * * * Author: Alexander Vladishev * * * ******************************************************************************/ void send_proxyconfig(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_proxyconfig"; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], *error = NULL; struct zbx_json j; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != get_active_proxy_id(jp, &proxy_hostid, host, &error)) { zbx_send_response(sock, FAIL, error, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_WARNING, "proxy configuration request from active proxy on \"%s\" failed: %s", get_ip_by_socket(sock), error); goto out; } update_proxy_lastaccess(proxy_hostid); zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); if (SUCCEED != get_proxyconfig_data(proxy_hostid, &j, &error)) { zbx_send_response(sock, FAIL, error, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_WARNING, "cannot collect proxy configuration: %s", error); goto clean; } zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\", datalen " ZBX_FS_SIZE_T, host, (zbx_fs_size_t)j.buffer_size); zabbix_log(LOG_LEVEL_DEBUG, "%s", j.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, j.buffer)) zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration: %s", zbx_tcp_strerror()); alarm(0); clean: zbx_json_free(&j); out: zbx_free(error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: recv_proxy_heartbeat * * * * Purpose: process heartbeat sent by proxy servers * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void recv_proxy_heartbeat(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_proxy_heartbeat"; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], error[256]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == get_proxy_id(jp, &proxy_hostid, host, error, sizeof(error))) { zabbix_log(LOG_LEVEL_WARNING, "Heartbeat from active proxy on [%s] failed: %s", get_ip_by_socket(sock), error); return; } update_proxy_lastaccess(proxy_hostid); zbx_send_response(sock, SUCCEED, NULL, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: send_proxyconfig * * * * Purpose: send configuration tables to the proxy from server * * (for active proxies) * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void send_proxyconfig(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_proxyconfig"; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], error[256]; struct zbx_json j; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == get_proxy_id(jp, &proxy_hostid, host, error, sizeof(error))) { zabbix_log(LOG_LEVEL_WARNING, "Proxy config request from active proxy on [%s] failed: %s", get_ip_by_socket(sock), error); return; } update_proxy_lastaccess(proxy_hostid); zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); get_proxyconfig_data(proxy_hostid, &j); zabbix_log(LOG_LEVEL_WARNING, "Sending configuration data to proxy '%s'. Datalen " ZBX_FS_SIZE_T, host, (zbx_fs_size_t)j.buffer_size); zabbix_log(LOG_LEVEL_DEBUG, "%s", j.buffer); alarm(CONFIG_TIMEOUT); if (FAIL == zbx_tcp_send(sock, j.buffer)) zabbix_log(LOG_LEVEL_WARNING, "Error while sending configuration. %s", zbx_tcp_strerror()); alarm(0); zbx_json_free(&j); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: recv_discovery_data * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void recv_discovery_data(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_discovery_data"; int ret; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], error[256]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == (ret = get_proxy_id(jp, &proxy_hostid, host, error, sizeof(error)))) { zabbix_log(LOG_LEVEL_WARNING, "Discovery data from active proxy on [%s] failed: %s", get_ip_by_socket(sock), error); goto exit; } process_dhis_data(jp); exit: zbx_send_response(sock, ret, NULL, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); }
/****************************************************************************** * * * Function: recv_proxyhistory * * * * Purpose: process values sent by proxy servers * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void recv_proxyhistory(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_proxyhistory"; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], info[128], error[256]; int ret; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == (ret = get_proxy_id(jp, &proxy_hostid, host, error, sizeof(error)))) { zabbix_log(LOG_LEVEL_WARNING, "History data from active proxy on [%s] failed: %s", get_ip_by_socket(sock), error); goto exit; } update_proxy_lastaccess(proxy_hostid); ret = process_hist_data(sock, jp, proxy_hostid, info, sizeof(info)); exit: zbx_send_response(sock, ret, info, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent succesfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_sock_t *sock, char *request) { char *host = NULL, *p; DB_RESULT result; DB_ROW row; char *buffer = NULL; int buffer_alloc = 2048; int buffer_offset = 0; int res = FAIL; zbx_uint64_t hostid; char error[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In send_list_of_active_checks()"); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, MAX_STRING_LEN, "host is null"); goto out; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto out; buffer = zbx_malloc(buffer, buffer_alloc); buffer_offset = 0; zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 1024, "select i.key_,i.delay,i.lastlogsize from items i,hosts h" " where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid=0", HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, hostid); if (0 != CONFIG_REFRESH_UNSUPPORTED) { zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 256, " and (i.status=%d or (i.status=%d and i.nextcheck<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, time(NULL)); } else { zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 256, " and i.status=%d", ITEM_STATUS_ACTIVE); } result = DBselect("%s", buffer); buffer_offset = 0; while (NULL != (row = DBfetch(result))) { zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 512, "%s:%s:%s\n", row[0], row[1], row[2]); } DBfree_result(result); zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 512, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", buffer); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; zbx_free(buffer); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "Send list of active checks to [%s] failed: %s", get_ip_by_socket(sock), error); return res; }
/****************************************************************************** * * * Function: send_list_of_active_checks_json * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * json - request buffer * * * * Return value: SUCCEED - list of active checks sent succesfully * * FAIL - an error occured * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_sock_t *sock, struct zbx_json_parse *jp) { char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32]; DB_RESULT result; DB_ROW row; DB_ITEM item; struct zbx_json json; int res = FAIL; zbx_uint64_t hostid; char error[MAX_STRING_LEN]; char **regexp = NULL; int regexp_alloc = 32; int regexp_num = 0, n; char *sql = NULL; int sql_alloc = 2048; int sql_offset; zabbix_log(LOG_LEVEL_DEBUG, "In send_list_of_active_checks_json()"); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror()); goto out; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto out; regexp = zbx_malloc(regexp, regexp_alloc); sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 1024, "select %s where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid=0", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, hostid); if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and (i.status=%d or (i.status=%d and i.nextcheck<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, time(NULL)); else zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and i.status=%d", ITEM_STATUS_ACTIVE); zbx_free(name_esc); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { DBget_item_from_db(&item, row); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, item.key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(item.key, item.key_orig)) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, item.key_orig, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.delay); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, tmp, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.lastlogsize); zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, ZBX_JSON_TYPE_STRING); zbx_json_close(&json); /* Special processing for log[] and eventlog[] items */ do { /* simple try realization */ if (0 != strncmp(item.key, "log[", 4) && 0 != strncmp(item.key, "eventlog[", 9)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break;; if (0 != get_param(params, 2, pattern, sizeof(pattern))) break; if (*pattern != '@') break; for (n = 0; n < regexp_num; n++) if (0 == strcmp(regexp[n], pattern + 1)) break; if (n != regexp_num) break; if (regexp_num == regexp_alloc) { regexp_alloc += 32; regexp = zbx_realloc(regexp, regexp_alloc); } regexp[regexp_num++] = strdup(pattern + 1); } while (0); /* simple try realization */ } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e where r.regexpid=e.regexpid and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, ")"); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", json.buffer); if (SUCCEED != zbx_tcp_send_raw(sock, json.buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; zbx_json_free(&json); zbx_free(sql); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "Send list of active checks to [%s] failed: %s", get_ip_by_socket(sock), error); return res; }
/****************************************************************************** * * * Function: zbx_tcp_recv_ext * * * * Purpose: receive data * * * * Return value: number of bytes received - success, * * FAIL - an error occurred * * * * Author: Eugene Grigorjev * * * ******************************************************************************/ ssize_t zbx_tcp_recv_ext(zbx_sock_t *s, char **data, unsigned char flags, int timeout) { #define ZBX_BUF_LEN (ZBX_STAT_BUF_LEN * 8) ssize_t nbytes, left, total_bytes; size_t allocated, offset, read_bytes; zbx_uint64_t expected_len; ZBX_TCP_START(); if (0 != timeout) zbx_tcp_timeout_set(s, timeout); zbx_free(s->buf_dyn); total_bytes = 0; read_bytes = 0; s->buf_type = ZBX_BUF_TYPE_STAT; *data = s->buf_stat; left = ZBX_TCP_HEADER_LEN; if (ZBX_TCP_ERROR == (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, left))) goto out; if (ZBX_TCP_HEADER_LEN == nbytes && 0 == strncmp(s->buf_stat, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN)) { total_bytes += nbytes; left = sizeof(zbx_uint64_t); if (left != (nbytes = ZBX_TCP_READ(s->socket, (void *)&expected_len, left))) { total_bytes = FAIL; goto out; } expected_len = zbx_letoh_uint64(expected_len); if (ZBX_MAX_RECV_DATA_SIZE < expected_len) { zabbix_log(LOG_LEVEL_WARNING, "Message size " ZBX_FS_UI64 " from %s" " exceeds the maximum size " ZBX_FS_UI64 " bytes. Message ignored.", expected_len, get_ip_by_socket(s), (zbx_uint64_t)ZBX_MAX_RECV_DATA_SIZE); total_bytes = FAIL; goto cleanup; } flags |= ZBX_TCP_READ_UNTIL_CLOSE; } else { read_bytes = nbytes; expected_len = 16 * ZBX_MEBIBYTE; } s->buf_stat[read_bytes] = '\0'; if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE)) { if (0 == nbytes) goto cleanup; } else { if (nbytes < left) goto cleanup; } left = sizeof(s->buf_stat) - read_bytes - 1; /* check for an empty socket if exactly ZBX_TCP_HEADER_LEN bytes (without a header) were sent */ if (0 == read_bytes || '\n' != s->buf_stat[read_bytes - 1]) /* requests to passive agents end with '\n' */ { /* fill static buffer */ while (read_bytes < expected_len && 0 < left && ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat + read_bytes, left))) { read_bytes += nbytes; if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE)) { if (0 == nbytes) break; } else { if (nbytes < left) /* should we stop reading? */ { /* XML protocol? */ if (0 == strncmp(s->buf_stat, "<req>", sizeof("<req>") - 1)) { /* closing tag received in the last 10 bytes? */ s->buf_stat[read_bytes] = '\0'; if (NULL != strstr(s->buf_stat + read_bytes - (10 > read_bytes ? read_bytes : 10), "</req>")) break; } else break; } } left -= nbytes; } } s->buf_stat[read_bytes] = '\0'; if (sizeof(s->buf_stat) - 1 == read_bytes) /* static buffer is full */ { allocated = ZBX_BUF_LEN; s->buf_type = ZBX_BUF_TYPE_DYN; s->buf_dyn = zbx_malloc(s->buf_dyn, allocated); memcpy(s->buf_dyn, s->buf_stat, sizeof(s->buf_stat)); offset = read_bytes; /* fill dynamic buffer */ while (read_bytes < expected_len && ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, sizeof(s->buf_stat)))) { zbx_strncpy_alloc(&s->buf_dyn, &allocated, &offset, s->buf_stat, nbytes); read_bytes += nbytes; if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE)) { if (0 == nbytes) break; } else { if ((size_t)nbytes < sizeof(s->buf_stat) - 1) /* should we stop reading? */ { /* XML protocol? */ if (0 == strncmp(s->buf_dyn, "<req>", sizeof("<req>") - 1)) { /* closing tag received in the last 10 bytes? */ if (NULL != strstr(s->buf_dyn + read_bytes - 10, "</req>")) break; } else break; } } } *data = s->buf_dyn; } out: if (ZBX_TCP_ERROR == nbytes) { zbx_set_tcp_strerror("ZBX_TCP_READ() failed: %s", strerror_from_system(zbx_sock_last_error())); total_bytes = FAIL; } cleanup: if (0 != timeout) zbx_tcp_timeout_cleanup(s); if (FAIL != total_bytes) total_bytes += read_bytes; return total_bytes; }
/****************************************************************************** * * * Function: send_list_of_active_checks_json * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * json - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32], key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; DB_RESULT result; DB_ROW row; struct zbx_json json; int res = FAIL, refresh_unsupported, now; zbx_uint64_t hostid; char error[MAX_STRING_LEN], *key = NULL; DC_ITEM dc_item; unsigned short port; char **regexp = NULL; int regexp_alloc = 0; int regexp_num = 0, n; char *sql = NULL; size_t sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror()); goto error; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, get_ip_by_socket(sock)); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp))) *tmp = '\0'; if (FAIL == is_ushort(tmp, &port)) port = ZBX_DEFAULT_AGENT_PORT; if (FAIL == get_hostid_by_host(host, ip, port, &hostid, error)) goto error; DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select i.key_,i.delay,i.lastlogsize,i.mtime" " from items i,hosts h" " where i.hostid=h.hostid" " and h.status=%d" " and i.type=%d" " and i.flags<>%d" " and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid is null", HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, ZBX_FLAG_DISCOVERY_CHILD, hostid); zbx_free(name_esc); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[0])) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was not found in the server cache. Not sending now.", __function_name, row[0]); continue; } if (ITEM_STATUS_NOTSUPPORTED == dc_item.status) { if (0 == refresh_unsupported || dc_item.lastclock + refresh_unsupported > now) { DCconfig_clean_items(&dc_item, NULL, 1); continue; } } zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was successfully found in the server cache. Sending.", __function_name, row[0]); ZBX_STRDUP(key, row[0]); substitute_key_macros(&key, NULL, &dc_item, NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); DCconfig_clean_items(&dc_item, NULL, 1); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(key, row[0])) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, row[1], ZBX_JSON_TYPE_INT); /* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */ zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, row[3], ZBX_JSON_TYPE_INT); zbx_json_close(&json); /* special processing for log[] and logrt[] items */ do { /* simple try realization */ /* log[filename,pattern,encoding,maxlinespersec] */ /* logrt[filename_format,pattern,encoding,maxlinespersec] */ if (0 != strncmp(key, "log[", 4) && 0 != strncmp(key, "logrt[", 6)) break; if (2 != parse_command(key, NULL, 0, params, sizeof(params))) break; /* dealing with `pattern' parameter */ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); } while (0); /* simple try realization */ /* special processing for eventlog[] items */ do { /* simple try realization */ /* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */ if (0 != strncmp(key, "eventlog[", 9)) break; if (2 != parse_command(key, NULL, 0, params, sizeof(params))) break; /* dealing with `pattern' parameter */ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); /* dealing with `severity' parameter */ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /* dealing with `logeventid' parameter */ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_logeventid + 1); } while (0); /* simple try realization */ zbx_free(key); } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e" " where r.regexpid=e.regexpid" " and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')'); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, DB_NODE, DBnode_local("r.regexpid")); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_json_free(&json); zbx_free(sql); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), error); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); res = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_sock_t *sock, char *request) { const char *__function_name = "send_list_of_active_checks"; char *host = NULL, *p; DB_RESULT result; DB_ROW row; char *buffer = NULL; size_t buffer_alloc = 2 * ZBX_KIBIBYTE, buffer_offset = 0; int res = FAIL, refresh_unsupported, now; zbx_uint64_t hostid; char error[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; DC_ITEM dc_item; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, sizeof(error), "host is null"); goto out; } strscpy(ip, get_ip_by_socket(sock)); if (FAIL == get_hostid_by_host(host, ip, ZBX_DEFAULT_AGENT_PORT, &hostid, error)) goto out; DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); buffer = zbx_malloc(buffer, buffer_alloc); buffer_offset = 0; zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "select i.key_,i.delay,i.lastlogsize" " from items i,hosts h" " where i.hostid=h.hostid" " and h.status=%d" " and i.type=%d" " and i.flags<>%d" " and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid is null", HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, ZBX_FLAG_DISCOVERY_CHILD, hostid); result = DBselect("%s", buffer); buffer_offset = 0; while (NULL != (row = DBfetch(result))) { if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[0])) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was not found in the server cache. Not sending now.", __function_name, row[0]); continue; } if (ITEM_STATUS_NOTSUPPORTED == dc_item.status) { if (0 == refresh_unsupported || dc_item.lastclock + refresh_unsupported > now) { DCconfig_clean_items(&dc_item, NULL, 1); continue; } } DCconfig_clean_items(&dc_item, NULL, 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was successfully found in the server cache. Sending.", __function_name, row[0]); zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "%s:%s:%s\n", row[0], /* item key */ row[1], /* item delay */ row[2]); /* item lastlogsize */ } DBfree_result(result); zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_free(buffer); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: send_list_of_active_checks_json * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * json - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; #define ZBX_KEY_OTHER 0 #define ZBX_KEY_LOG 1 #define ZBX_KEY_EVENTLOG 2 char host[HOST_HOST_LEN_MAX], params[MAX_STRING_LEN], tmp[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX], error[MAX_STRING_LEN], *host_metadata = NULL; struct zbx_json json; int ret = FAIL, i; zbx_uint64_t hostid; size_t host_metadata_alloc = 1; /* for at least NUL-termination char */ unsigned short port; zbx_vector_uint64_t itemids; unsigned char item_key; zbx_vector_ptr_t regexps; zbx_vector_str_t names; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(®exps); zbx_vector_str_create(&names); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror()); goto error; } host_metadata = zbx_malloc(host_metadata, host_metadata_alloc); if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_HOST_METADATA, &host_metadata, &host_metadata_alloc)) { *host_metadata = '\0'; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, get_ip_by_socket(sock)); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp))) *tmp = '\0'; if (FAIL == is_ushort(tmp, &port)) port = ZBX_DEFAULT_AGENT_PORT; if (FAIL == get_hostid_by_host(host, ip, port, host_metadata, &hostid, error)) goto error; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, refresh_unsupported, now; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == refresh_unsupported || dc_items[i].lastclock + refresh_unsupported > now) continue; } dc_items[i].key = zbx_strdup(dc_items[i].key, dc_items[i].key_orig); substitute_key_macros(&dc_items[i].key, NULL, &dc_items[i], NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig)) { zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, dc_items[i].key_orig, ZBX_JSON_TYPE_STRING); } zbx_json_adduint64(&json, ZBX_PROTO_TAG_DELAY, dc_items[i].delay); /* The agent expects ALWAYS to have lastlogsize and mtime tags. */ /* Removing those would cause older agents to fail. */ zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGLASTSIZE, dc_items[i].lastlogsize); zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime); zbx_json_close(&json); if (0 == strncmp(dc_items[i].key, "log[", 4) || 0 == strncmp(dc_items[i].key, "logrt[", 6)) item_key = ZBX_KEY_LOG; else if (0 == strncmp(dc_items[i].key, "eventlog[", 9)) item_key = ZBX_KEY_EVENTLOG; else item_key = ZBX_KEY_OTHER; if (ZBX_KEY_OTHER != item_key && ZBX_COMMAND_WITH_PARAMS == parse_command(dc_items[i].key, NULL, 0, params, sizeof(params))) { /* "params" parameter */ if (0 == get_param(params, 2, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); if (ZBX_KEY_EVENTLOG == item_key) { /* "severity" parameter */ if (0 == get_param(params, 3, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); /* "source" parameter */ if (0 == get_param(params, 4, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); /* "logeventid" parameter */ if (0 == get_param(params, 5, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); } } zbx_free(dc_items[i].key); } DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_json_close(&json); DCget_expressions_by_names(®exps, (const char * const *)names.values, names.values_num); if (0 < regexps.values_num) { char buffer[32]; zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); for (i = 0; i < regexps.values_num; i++) { zbx_expression_t *regexp = regexps.values[i]; zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", regexp->name, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", regexp->expression, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->expression_type); zbx_json_addstring(&json, "expression_type", buffer, ZBX_JSON_TYPE_INT); zbx_snprintf(buffer, sizeof(buffer), "%c", regexp->exp_delimiter); zbx_json_addstring(&json, "exp_delimiter", buffer, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->case_sensitive); zbx_json_addstring(&json, "case_sensitive", buffer, ZBX_JSON_TYPE_INT); zbx_json_close(&json); } zbx_json_close(&json); } zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_tcp_strerror()); else ret = SUCCEED; alarm(0); zbx_json_free(&json); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), error); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); ret = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: for (i = 0; i < names.values_num; i++) zbx_free(names.values[i]); zbx_vector_str_destroy(&names); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); zbx_free(host_metadata); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host (older version agent) * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_sock_t *sock, char *request) { const char *__function_name = "send_list_of_active_checks"; char *host = NULL, *p, *buffer = NULL, error[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; size_t buffer_alloc = 8 * ZBX_KIBIBYTE, buffer_offset = 0; int ret = FAIL, i; zbx_uint64_t hostid; zbx_vector_uint64_t itemids; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, sizeof(error), "host is null"); goto out; } strscpy(ip, get_ip_by_socket(sock)); /* no host metadata in older versions of agent */ if (FAIL == get_hostid_by_host(host, ip, ZBX_DEFAULT_AGENT_PORT, "", &hostid, error)) goto out; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); buffer = zbx_malloc(buffer, buffer_alloc); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, refresh_unsupported, now; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == refresh_unsupported || dc_items[i].lastclock + refresh_unsupported > now) continue; } zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "%s:%d:" ZBX_FS_UI64 "\n", dc_items[i].key_orig, dc_items[i].delay, dc_items[i].lastlogsize); } DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_strlcpy(error, zbx_tcp_strerror(), MAX_STRING_LEN); else ret = SUCCEED; alarm(0); zbx_free(buffer); out: if (FAIL == ret) { zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), error); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * 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; }