summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/aclk/aclk.c8
-rw-r--r--src/aclk/aclk_otp.c25
-rw-r--r--src/aclk/aclk_otp.h6
-rw-r--r--src/aclk/https_client.c7
-rw-r--r--src/aclk/https_client.h2
-rw-r--r--src/aclk/mqtt_websockets/mqtt_wss_client.c7
-rw-r--r--src/aclk/mqtt_websockets/mqtt_wss_client.h10
-rw-r--r--src/daemon/commands.c28
-rw-r--r--src/database/sqlite/sqlite_aclk.c30
-rw-r--r--src/database/sqlite/sqlite_aclk_alert.c17
-rw-r--r--src/database/sqlite/sqlite_health.c4
-rw-r--r--src/go/plugin/go.d/agent/vnodes/vnodes.go30
-rw-r--r--src/go/plugin/go.d/modules/dnsmasq_dhcp/dhcp_test.go4
-rw-r--r--src/go/plugin/go.d/modules/dnsmasq_dhcp/parse_configuration.go10
-rw-r--r--src/go/plugin/go.d/modules/storcli/collect_drives.go24
-rw-r--r--src/libnetdata/gorilla/gorilla.cc7
-rw-r--r--src/libnetdata/socket/socket.c18
-rw-r--r--src/libnetdata/socket/socket.h9
-rw-r--r--src/streaming/receiver.c26
19 files changed, 176 insertions, 96 deletions
diff --git a/src/aclk/aclk.c b/src/aclk/aclk.c
index 627edfc91..389d7455f 100644
--- a/src/aclk/aclk.c
+++ b/src/aclk/aclk.c
@@ -600,6 +600,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client)
url_t mqtt_url;
#endif
+ bool fallback_ipv4 = false;
while (service_running(SERVICE_ACLK)) {
aclk_cloud_base_url = appconfig_get(&cloud_config, CONFIG_SECTION_GLOBAL, "cloud base url", NULL);
if (aclk_cloud_base_url == NULL) {
@@ -646,7 +647,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client)
}
aclk_env = callocz(1, sizeof(aclk_env_t));
- ret = aclk_get_env(aclk_env, base_url.host, base_url.port);
+ ret = aclk_get_env(aclk_env, base_url.host, base_url.port, &fallback_ipv4);
url_t_destroy(&base_url);
if(ret) switch(ret) {
case 1:
@@ -714,7 +715,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client)
continue;
}
- ret = aclk_get_mqtt_otp(aclk_private_key, (char **)&mqtt_conn_params.clientid, (char **)&mqtt_conn_params.username, (char **)&mqtt_conn_params.password, &auth_url);
+ ret = aclk_get_mqtt_otp(aclk_private_key, (char **)&mqtt_conn_params.clientid, (char **)&mqtt_conn_params.username, (char **)&mqtt_conn_params.password, &auth_url, &fallback_ipv4);
url_t_destroy(&auth_url);
if (ret) {
aclk_status = ACLK_STATUS_INVALID_OTP;
@@ -759,7 +760,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client)
ret = mqtt_wss_connect(client, base_url.host, base_url.port, &mqtt_conn_params, ACLK_SSL_FLAGS, &proxy_conf);
url_t_destroy(&base_url);
#else
- ret = mqtt_wss_connect(client, mqtt_url.host, mqtt_url.port, &mqtt_conn_params, ACLK_SSL_FLAGS, &proxy_conf);
+ ret = mqtt_wss_connect(client, mqtt_url.host, mqtt_url.port, &mqtt_conn_params, ACLK_SSL_FLAGS, &proxy_conf, &fallback_ipv4);
url_t_destroy(&mqtt_url);
freez((char*)mqtt_conn_params.clientid);
@@ -778,6 +779,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client)
aclk_status = ACLK_STATUS_CONNECTED;
nd_log(NDLS_ACCESS, NDLP_INFO, "ACLK CONNECTED");
mqtt_connected_actions(client);
+ fallback_ipv4 = false;
return 0;
}
diff --git a/src/aclk/aclk_otp.c b/src/aclk/aclk_otp.c
index c9c75dd38..3b8222931 100644
--- a/src/aclk/aclk_otp.c
+++ b/src/aclk/aclk_otp.c
@@ -1,4 +1,3 @@
-
// SPDX-License-Identifier: GPL-3.0-or-later
#include "aclk_otp.h"
@@ -9,7 +8,7 @@
#include "mqtt_websockets/c-rbuf/cringbuffer.h"
-static int aclk_https_request(https_req_t *request, https_req_response_t *response) {
+static int aclk_https_request(https_req_t *request, https_req_response_t *response, bool *fallback_ipv4) {
int rc;
// wrapper for ACLK only which loads ACLK specific proxy settings
// then only calls https_request
@@ -23,7 +22,7 @@ static int aclk_https_request(https_req_t *request, https_req_response_t *respon
request->proxy_password = proxy_conf.password;
}
- rc = https_request(request, response);
+ rc = https_request(request, response, fallback_ipv4);
freez((char*)proxy_conf.host);
freez((char*)proxy_conf.username);
freez((char*)proxy_conf.password);
@@ -308,7 +307,7 @@ inline static int base64_decode_helper(unsigned char *out, int *outl, const unsi
}
#define OTP_URL_PREFIX "/api/v1/auth/node/"
-int aclk_get_otp_challenge(url_t *target, const char *agent_id, unsigned char **challenge, int *challenge_bytes)
+int aclk_get_otp_challenge(url_t *target, const char *agent_id, unsigned char **challenge, int *challenge_bytes, bool *fallback_ipv4)
{
int rc = 1;
https_req_t req = HTTPS_REQ_T_INITIALIZER;
@@ -321,7 +320,7 @@ int aclk_get_otp_challenge(url_t *target, const char *agent_id, unsigned char **
buffer_sprintf(url, "%s/node/%s/challenge", target->path, agent_id);
req.url = (char *)buffer_tostring(url);
- if (aclk_https_request(&req, &resp)) {
+ if (aclk_https_request(&req, &resp, fallback_ipv4)) {
netdata_log_error("ACLK_OTP Challenge failed");
buffer_free(url);
return 1;
@@ -378,7 +377,7 @@ cleanup_resp:
return rc;
}
-int aclk_send_otp_response(const char *agent_id, const unsigned char *response, int response_bytes, url_t *target, struct auth_data *mqtt_auth)
+int aclk_send_otp_response(const char *agent_id, const unsigned char *response, int response_bytes, url_t *target, struct auth_data *mqtt_auth, bool *fallback_ipv4)
{
int len;
int rc = 1;
@@ -404,7 +403,7 @@ int aclk_send_otp_response(const char *agent_id, const unsigned char *response,
req.payload = (char *)buffer_tostring(resp_json);
req.payload_size = strlen(req.payload);
- if (aclk_https_request(&req, &resp)) {
+ if (aclk_https_request(&req, &resp, fallback_ipv4)) {
netdata_log_error("ACLK_OTP Password error trying to post result to password");
goto cleanup_buffers;
}
@@ -480,9 +479,9 @@ static int private_decrypt(RSA *p_key, unsigned char * enc_data, int data_len, u
}
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_300
-int aclk_get_mqtt_otp(EVP_PKEY *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target)
+int aclk_get_mqtt_otp(EVP_PKEY *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target, bool *fallback_ipv4)
#else
-int aclk_get_mqtt_otp(RSA *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target)
+int aclk_get_mqtt_otp(RSA *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target, bool *fallback_ipv4)
#endif
{
unsigned char *challenge = NULL;
@@ -495,7 +494,7 @@ int aclk_get_mqtt_otp(RSA *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_p
}
// Get Challenge
- if (aclk_get_otp_challenge(target, agent_id, &challenge, &challenge_bytes)) {
+ if (aclk_get_otp_challenge(target, agent_id, &challenge, &challenge_bytes, fallback_ipv4)) {
netdata_log_error("Error getting challenge");
freez(agent_id);
return 1;
@@ -515,7 +514,7 @@ int aclk_get_mqtt_otp(RSA *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_p
// Encode and Send Challenge
struct auth_data data = { .client_id = NULL, .passwd = NULL, .username = NULL };
- if (aclk_send_otp_response(agent_id, response_plaintext, response_plaintext_bytes, target, &data)) {
+ if (aclk_send_otp_response(agent_id, response_plaintext, response_plaintext_bytes, target, &data, fallback_ipv4)) {
netdata_log_error("Error getting response");
freez(response_plaintext);
freez(agent_id);
@@ -823,7 +822,7 @@ exit:
return 1;
}
-int aclk_get_env(aclk_env_t *env, const char* aclk_hostname, int aclk_port) {
+int aclk_get_env(aclk_env_t *env, const char* aclk_hostname, int aclk_port, bool *fallback_ipv4) {
BUFFER *buf = buffer_create(1024, &netdata_buffers_statistics.buffers_aclk);
https_req_t req = HTTPS_REQ_T_INITIALIZER;
@@ -846,7 +845,7 @@ int aclk_get_env(aclk_env_t *env, const char* aclk_hostname, int aclk_port) {
req.host = (char*)aclk_hostname;
req.port = aclk_port;
req.url = buf->buffer;
- if (aclk_https_request(&req, &resp)) {
+ if (aclk_https_request(&req, &resp, fallback_ipv4)) {
netdata_log_error("Error trying to contact env endpoint");
https_req_response_free(&resp);
buffer_free(buf);
diff --git a/src/aclk/aclk_otp.h b/src/aclk/aclk_otp.h
index 2d660e5a4..a4a3a60b7 100644
--- a/src/aclk/aclk_otp.h
+++ b/src/aclk/aclk_otp.h
@@ -9,10 +9,10 @@
#include "aclk_util.h"
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_300
-int aclk_get_mqtt_otp(EVP_PKEY *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target);
+int aclk_get_mqtt_otp(EVP_PKEY *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target, bool *fallback_ipv4);
#else
-int aclk_get_mqtt_otp(RSA *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target);
+int aclk_get_mqtt_otp(RSA *p_key, char **mqtt_id, char **mqtt_usr, char **mqtt_pass, url_t *target, bool *fallback_ipv4);
#endif
-int aclk_get_env(aclk_env_t *env, const char *aclk_hostname, int aclk_port);
+int aclk_get_env(aclk_env_t *env, const char *aclk_hostname, int aclk_port, bool *fallback_ipv4);
#endif /* ACLK_OTP_H */
diff --git a/src/aclk/https_client.c b/src/aclk/https_client.c
index 8c44f13e3..4a0362992 100644
--- a/src/aclk/https_client.c
+++ b/src/aclk/https_client.c
@@ -620,13 +620,14 @@ static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
return preverify_ok;
}
-int https_request(https_req_t *request, https_req_response_t *response) {
+int https_request(https_req_t *request, https_req_response_t *response, bool *fallback_ipv4)
+{
int rc = 1, ret;
char connect_port_str[PORT_STR_MAX_BYTES];
const char *connect_host = request->proxy_host ? request->proxy_host : request->host;
int connect_port = request->proxy_host ? request->proxy_port : request->port;
- struct timeval timeout = { .tv_sec = request->timeout_s, .tv_usec = 0 };
+ struct timeval timeout = { .tv_sec = 10, .tv_usec = 0 };
https_req_ctx_t *ctx = callocz(1, sizeof(https_req_ctx_t));
ctx->req_start_time = now_realtime_sec();
@@ -639,7 +640,7 @@ int https_request(https_req_t *request, https_req_response_t *response) {
snprintfz(connect_port_str, PORT_STR_MAX_BYTES, "%d", connect_port);
- ctx->sock = connect_to_this_ip46(IPPROTO_TCP, SOCK_STREAM, connect_host, 0, connect_port_str, &timeout);
+ ctx->sock = connect_to_this_ip46(IPPROTO_TCP, SOCK_STREAM, connect_host, 0, connect_port_str, &timeout, fallback_ipv4);
if (ctx->sock < 0) {
netdata_log_error("Error connecting TCP socket to \"%s\"", connect_host);
goto exit_buf_rx;
diff --git a/src/aclk/https_client.h b/src/aclk/https_client.h
index bc5ca30b8..cf14ffd87 100644
--- a/src/aclk/https_client.h
+++ b/src/aclk/https_client.h
@@ -78,7 +78,7 @@ void https_req_response_free(https_req_response_t *res);
.proxy_port = 8080 \
}
-int https_request(https_req_t *request, https_req_response_t *response);
+int https_request(https_req_t *request, https_req_response_t *response, bool *fallback_ipv4);
// we expose previously internal parser as this is usefull also from
// other parts of the code
diff --git a/src/aclk/mqtt_websockets/mqtt_wss_client.c b/src/aclk/mqtt_websockets/mqtt_wss_client.c
index 2d231ef44..bb0e17262 100644
--- a/src/aclk/mqtt_websockets/mqtt_wss_client.c
+++ b/src/aclk/mqtt_websockets/mqtt_wss_client.c
@@ -522,7 +522,8 @@ int mqtt_wss_connect(
int port,
struct mqtt_connect_params *mqtt_params,
int ssl_flags,
- struct mqtt_wss_proxy *proxy)
+ struct mqtt_wss_proxy *proxy,
+ bool *fallback_ipv4)
{
if (!mqtt_params) {
mws_error(client->log, "mqtt_params can't be null!");
@@ -578,7 +579,9 @@ int mqtt_wss_connect(
char port_str[16];
snprintf(port_str, sizeof(port_str) -1, "%d", client->port);
- int fd = connect_to_this_ip46(IPPROTO_TCP, SOCK_STREAM, client->host, 0, port_str, NULL);
+
+ struct timeval timeout = { .tv_sec = 10, .tv_usec = 0 };
+ int fd = connect_to_this_ip46(IPPROTO_TCP, SOCK_STREAM, client->host, 0, port_str, &timeout, fallback_ipv4);
if (fd < 0) {
mws_error(client->log, "Could not connect to remote endpoint \"%s\", port %d.\n", client->host, port);
return -3;
diff --git a/src/aclk/mqtt_websockets/mqtt_wss_client.h b/src/aclk/mqtt_websockets/mqtt_wss_client.h
index 4bdea4db9..f0bdce98b 100644
--- a/src/aclk/mqtt_websockets/mqtt_wss_client.h
+++ b/src/aclk/mqtt_websockets/mqtt_wss_client.h
@@ -4,6 +4,7 @@
#ifndef MQTT_WSS_CLIENT_H
#define MQTT_WSS_CLIENT_H
+#include <stdbool.h>
#include <stdint.h>
#include <stddef.h> //size_t
@@ -69,7 +70,14 @@ struct mqtt_wss_proxy;
* @param mqtt_params pointer to mqtt_connect_params structure which contains MQTT credentials and settings
* @param ssl_flags parameters for OpenSSL, 0=MQTT_WSS_SSL_CERT_CHECK_FULL
*/
-int mqtt_wss_connect(mqtt_wss_client client, char *host, int port, struct mqtt_connect_params *mqtt_params, int ssl_flags, struct mqtt_wss_proxy *proxy);
+int mqtt_wss_connect(
+ mqtt_wss_client client,
+ char *host,
+ int port,
+ struct mqtt_connect_params *mqtt_params,
+ int ssl_flags,
+ struct mqtt_wss_proxy *proxy,
+ bool *fallback_ipv4);
int mqtt_wss_service(mqtt_wss_client client, int timeout_ms);
void mqtt_wss_disconnect(mqtt_wss_client client, int timeout_ms);
diff --git a/src/daemon/commands.c b/src/daemon/commands.c
index 230e8527e..f0637ad31 100644
--- a/src/daemon/commands.c
+++ b/src/daemon/commands.c
@@ -112,32 +112,32 @@ static cmd_status_t cmd_help_execute(char *args, char **message)
*message = mallocz(MAX_COMMAND_LENGTH);
strncpyz(*message,
- "\nThe commands are (arguments are in brackets):\n"
+ "\nThe commands are:\n\n"
"help\n"
- " Show this help menu.\n"
+ " Show this help menu.\n\n"
"reload-health\n"
- " Reload health configuration.\n"
+ " Reload health configuration.\n\n"
"reload-labels\n"
- " Reload all labels.\n"
+ " Reload all labels.\n\n"
"save-database\n"
- " Save internal DB to disk for memory mode save.\n"
+ " Save internal DB to disk for memory mode save.\n\n"
"reopen-logs\n"
- " Close and reopen log files.\n"
+ " Close and reopen log files.\n\n"
"shutdown-agent\n"
- " Cleanup and exit the netdata agent.\n"
+ " Cleanup and exit the netdata agent.\n\n"
"fatal-agent\n"
- " Log the state and halt the netdata agent.\n"
+ " Log the state and halt the netdata agent.\n\n"
"reload-claiming-state\n"
- " Reload agent claiming state from disk.\n"
+ " Reload agent claiming state from disk.\n\n"
"ping\n"
- " Return with 'pong' if agent is alive.\n"
+ " Return with 'pong' if agent is alive.\n\n"
"aclk-state [json]\n"
- " Returns current state of ACLK and Cloud connection. (optionally in json).\n"
+ " Returns current state of ACLK and Cloud connection. (optionally in json).\n\n"
"dumpconfig\n"
- " Returns the current netdata.conf on stdout.\n"
+ " Returns the current netdata.conf on stdout.\n\n"
#ifdef ENABLE_ACLK
- "remove-stale-node node_id|machine_guid|hostname|ALL_NODES\n"
- " Unregisters and removes a node from the cloud.\n"
+ "remove-stale-node <node_id | machine_guid | hostname | ALL_NODES>\n"
+ " Unregisters and removes a node from the cloud.\n\n"
#endif
"version\n"
" Returns the netdata version.\n",
diff --git a/src/database/sqlite/sqlite_aclk.c b/src/database/sqlite/sqlite_aclk.c
index 027ee8f93..adbe4d9d3 100644
--- a/src/database/sqlite/sqlite_aclk.c
+++ b/src/database/sqlite/sqlite_aclk.c
@@ -199,6 +199,34 @@ fail:
buffer_free(sql);
}
+#define SQL_INVALIDATE_HOST_LAST_CONNECTED "UPDATE host SET last_connected = 1 WHERE host_id = @host_id"
+
+static void invalidate_host_last_connected(nd_uuid_t *host_uuid)
+{
+ sqlite3_stmt *res = NULL;
+ if (!host_uuid)
+ return;
+
+ if (!PREPARE_STATEMENT(db_meta, SQL_INVALIDATE_HOST_LAST_CONNECTED, &res))
+ return;
+
+ int param = 0;
+ SQLITE_BIND_FAIL(bind_fail, sqlite3_bind_blob(res, ++param, host_uuid, sizeof(*host_uuid), SQLITE_STATIC));
+
+ param = 0;
+ int rc = sqlite3_step_monitored(res);
+ if (unlikely(rc != SQLITE_DONE)) {
+ char wstr[UUID_STR_LEN];
+ uuid_unparse_lower(*host_uuid, wstr);
+ error_report("Failed invalidate last_connected time for host with GUID %s, rc = %d", wstr, rc);
+ }
+
+bind_fail:
+ REPORT_BIND_FAIL(res, param);
+ SQLITE_FINALIZE(res);
+}
+
+
// OPCODE: ACLK_DATABASE_NODE_UNREGISTER
static void sql_unregister_node(char *machine_guid)
{
@@ -226,6 +254,7 @@ static void sql_unregister_node(char *machine_guid)
error_report("Failed to execute command to remove host node id");
} else {
// node: machine guid will be freed after processing
+ invalidate_host_last_connected(&host_uuid);
metadata_delete_host_chart_labels(machine_guid);
machine_guid = NULL;
}
@@ -329,7 +358,6 @@ static void aclk_synchronization(void *arg)
break;
case ACLK_DATABASE_NODE_UNREGISTER:
sql_unregister_node(cmd.param[0]);
-
break;
// ALERTS
case ACLK_DATABASE_PUSH_ALERT_CONFIG:
diff --git a/src/database/sqlite/sqlite_aclk_alert.c b/src/database/sqlite/sqlite_aclk_alert.c
index 3e7076169..dbe5a5045 100644
--- a/src/database/sqlite/sqlite_aclk_alert.c
+++ b/src/database/sqlite/sqlite_aclk_alert.c
@@ -488,10 +488,9 @@ done:
freez(claim_id);
}
-#define SQL_DELETE_PROCESSED_ROWS \
- "DELETE FROM alert_queue WHERE host_id = @host_id AND rowid between @row1 AND @row2"
+#define SQL_DELETE_PROCESSED_ROWS "DELETE FROM alert_queue WHERE host_id = @host_id AND rowid = @row"
-static void delete_alert_from_pending_queue(RRDHOST *host, int64_t row1, int64_t row2)
+static void delete_alert_from_pending_queue(RRDHOST *host, int64_t row)
{
static __thread sqlite3_stmt *res = NULL;
@@ -500,8 +499,7 @@ static void delete_alert_from_pending_queue(RRDHOST *host, int64_t row1, int64_t
int param = 0;
SQLITE_BIND_FAIL(done, sqlite3_bind_blob(res, ++param, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC));
- SQLITE_BIND_FAIL(done, sqlite3_bind_int64(res, ++param, row1));
- SQLITE_BIND_FAIL(done, sqlite3_bind_int64(res, ++param, row2));
+ SQLITE_BIND_FAIL(done, sqlite3_bind_int64(res, ++param, row));
param = 0;
int rc = sqlite3_step_monitored(res);
@@ -571,8 +569,6 @@ bool process_alert_pending_queue(RRDHOST *host)
SQLITE_BIND_FAIL(done, sqlite3_bind_blob(res, ++param, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC));
param = 0;
- int64_t start_row = 0;
- int64_t end_row = 0;
while (sqlite3_step_monitored(res) == SQLITE_ROW) {
int64_t health_log_id = sqlite3_column_int64(res, 0);
@@ -586,16 +582,11 @@ bool process_alert_pending_queue(RRDHOST *host)
added++;
}
- if (!start_row)
- start_row = row;
- end_row = row;
+ delete_alert_from_pending_queue(host, row);
count++;
}
- if (start_row)
- delete_alert_from_pending_queue(host, start_row, end_row);
-
if(count)
nd_log(NDLS_ACCESS, NDLP_NOTICE, "ACLK STA [%s (N/A)]: Processed %d entries, queued %d", rrdhost_hostname(host), count, added);
done:
diff --git a/src/database/sqlite/sqlite_health.c b/src/database/sqlite/sqlite_health.c
index a632fd494..9304c8c73 100644
--- a/src/database/sqlite/sqlite_health.c
+++ b/src/database/sqlite/sqlite_health.c
@@ -437,12 +437,10 @@ static void sql_inject_removed_status(
int64_t health_log_id = sqlite3_column_int64(res, 0);
RRDCALC_STATUS old_status = (RRDCALC_STATUS)sqlite3_column_double(res, 1);
insert_alert_queue(
- host, health_log_id, (int64_t)unique_id, (int64_t)alarm_id, old_status, RRDCALC_STATUS_REMOVED);
+ host, health_log_id, (int64_t)max_unique_id, (int64_t)alarm_id, old_status, RRDCALC_STATUS_REMOVED);
}
#endif
}
- //else
- // error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED, rc = %d", rc);
done:
REPORT_BIND_FAIL(res, param);
diff --git a/src/go/plugin/go.d/agent/vnodes/vnodes.go b/src/go/plugin/go.d/agent/vnodes/vnodes.go
index 9272f1514..3d332c261 100644
--- a/src/go/plugin/go.d/agent/vnodes/vnodes.go
+++ b/src/go/plugin/go.d/agent/vnodes/vnodes.go
@@ -61,11 +61,39 @@ func (vn *Vnodes) readConfDir() {
return nil
}
- if !d.Type().IsRegular() || !isConfigFile(path) {
+ if d.Type()&os.ModeSymlink != 0 {
+ dst, err := os.Readlink(path)
+ if err != nil {
+ vn.Warningf("failed to resolve symlink '%s': %v", path, err)
+ return nil
+ }
+
+ if !filepath.IsAbs(dst) {
+ dst = filepath.Join(filepath.Dir(path), filepath.Clean(dst))
+ }
+
+ fi, err := os.Stat(dst)
+ if err != nil {
+ vn.Warningf("failed to stat resolved path '%s': %v", dst, err)
+ return nil
+ }
+ if !fi.Mode().IsRegular() {
+ vn.Debugf("'%s' is not a regular file, skipping it", dst)
+ return nil
+ }
+ path = dst
+ } else if !d.Type().IsRegular() {
+ vn.Debugf("'%s' is not a regular file, skipping it", path)
+ return nil
+ }
+
+ if !isConfigFile(path) {
+ vn.Debugf("'%s' is not a config file (wrong extension), skipping it", path)
return nil
}
var cfg []VirtualNode
+
if err := loadConfigFile(&cfg, path); err != nil {
vn.Warning(err)
return nil
diff --git a/src/go/plugin/go.d/modules/dnsmasq_dhcp/dhcp_test.go b/src/go/plugin/go.d/modules/dnsmasq_dhcp/dhcp_test.go
index 16e0f17d0..a5774ae4a 100644
--- a/src/go/plugin/go.d/modules/dnsmasq_dhcp/dhcp_test.go
+++ b/src/go/plugin/go.d/modules/dnsmasq_dhcp/dhcp_test.go
@@ -193,6 +193,10 @@ func TestDnsmasqDHCP_parseDHCPRangeValue(t *testing.T) {
wantFail: true,
input: "1234::,ra-stateless",
},
+ "invalid": {
+ wantFail: true,
+ input: "192.168.0.0",
+ },
}
for name, test := range tests {
diff --git a/src/go/plugin/go.d/modules/dnsmasq_dhcp/parse_configuration.go b/src/go/plugin/go.d/modules/dnsmasq_dhcp/parse_configuration.go
index 558ce7c65..5ef29f28e 100644
--- a/src/go/plugin/go.d/modules/dnsmasq_dhcp/parse_configuration.go
+++ b/src/go/plugin/go.d/modules/dnsmasq_dhcp/parse_configuration.go
@@ -108,14 +108,12 @@ func parseDHCPRangeValue(s string) (r string) {
var start, end net.IP
parts := strings.Split(s, ",")
- for i, v := range parts {
- if start = net.ParseIP(strings.TrimSpace(v)); start == nil {
+ for _, v := range parts {
+ if start == nil {
+ start = net.ParseIP(v)
continue
}
- if len(parts) < i+1 {
- return ""
- }
- if end = net.ParseIP(parts[i+1]); end == nil || iprange.New(start, end) == nil {
+ if end = net.ParseIP(v); end == nil || iprange.New(start, end) == nil {
return ""
}
return fmt.Sprintf("%s-%s", start, end)
diff --git a/src/go/plugin/go.d/modules/storcli/collect_drives.go b/src/go/plugin/go.d/modules/storcli/collect_drives.go
index 5c2ecb387..95965d572 100644
--- a/src/go/plugin/go.d/modules/storcli/collect_drives.go
+++ b/src/go/plugin/go.d/modules/storcli/collect_drives.go
@@ -23,18 +23,18 @@ type drivesInfoResponse struct {
type (
driveInfo struct {
EIDSlt string `json:"EID:Slt"`
- DID int `json:"DID"`
- State string `json:"State"`
- DG int `json:"DG"`
- Size string `json:"Size"`
- Intf string `json:"Intf"`
- Med string `json:"Med"`
- SED string `json:"SED"`
- PI string `json:"PI"`
- SeSz string `json:"SeSz"`
- Model string `json:"Model"`
- Sp string `json:"Sp"`
- Type string `json:"Type"`
+ //DID int `json:"DID"`
+ //State string `json:"State"`
+ //DG int `json:"DG"` // FIX: can be integer or "-"
+ //Size string `json:"Size"`
+ //Intf string `json:"Intf"`
+ Med string `json:"Med"`
+ //SED string `json:"SED"`
+ //PI string `json:"PI"`
+ //SeSz string `json:"SeSz"`
+ //Model string `json:"Model"`
+ //Sp string `json:"Sp"`
+ //Type string `json:"Type"`
}
driveState struct {
MediaErrorCount storNumber `json:"Media Error Count"`
diff --git a/src/libnetdata/gorilla/gorilla.cc b/src/libnetdata/gorilla/gorilla.cc
index c76018365..e3d612418 100644
--- a/src/libnetdata/gorilla/gorilla.cc
+++ b/src/libnetdata/gorilla/gorilla.cc
@@ -162,10 +162,11 @@ bool gorilla_writer_write(gorilla_writer_t *gw, uint32_t number)
__atomic_fetch_add(&hdr->nbits, 1, __ATOMIC_RELAXED);
if (!is_xor_lzc_same) {
- if (hdr->nbits + 1 >= gw->capacity)
+ size_t bits_needed = (bit_size<uint32_t>() == 32) ? 5 : 6;
+ if ((hdr->nbits + bits_needed) >= gw->capacity)
return false;
- bit_buffer_write(data, hdr->nbits, xor_lzc, (bit_size<uint32_t>() == 32) ? 5 : 6);
- __atomic_fetch_add(&hdr->nbits, (bit_size<uint32_t>() == 32) ? 5 : 6, __ATOMIC_RELAXED);
+ bit_buffer_write(data, hdr->nbits, xor_lzc, bits_needed);
+ __atomic_fetch_add(&hdr->nbits, bits_needed, __ATOMIC_RELAXED);
}
// write the bits of the XOR'd value without the LZC prefix
diff --git a/src/libnetdata/socket/socket.c b/src/libnetdata/socket/socket.c
index 7170a3963..85f67a2ba 100644
--- a/src/libnetdata/socket/socket.c
+++ b/src/libnetdata/socket/socket.c
@@ -839,7 +839,15 @@ static inline int connect_to_unix(const char *path, struct timeval *timeout) {
// service the service name or port to connect to
// timeout the timeout for establishing a connection
-int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t scope_id, const char *service, struct timeval *timeout) {
+int connect_to_this_ip46(
+ int protocol,
+ int socktype,
+ const char *host,
+ uint32_t scope_id,
+ const char *service,
+ struct timeval *timeout,
+ bool *fallback_ipv4)
+{
struct addrinfo hints;
struct addrinfo *ai_head = NULL, *ai = NULL;
@@ -872,6 +880,9 @@ int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t
for (ai = ai_head; ai != NULL && fd == -1; ai = ai->ai_next) {
if(nd_thread_signaled_to_cancel()) break;
+ if (fallback_ipv4 && *fallback_ipv4 && ai->ai_family == PF_INET6)
+ continue;
+
if (ai->ai_family == PF_INET6) {
struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6 *) ai->ai_addr;
if(pSadrIn6->sin6_scope_id == 0) {
@@ -953,6 +964,9 @@ int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t
close(fd);
fd = -1;
+
+ if (fallback_ipv4 && ai->ai_family == PF_INET6)
+ *fallback_ipv4 = true;
break;
default:
@@ -1074,7 +1088,7 @@ int connect_to_this(const char *definition, int default_port, struct timeval *ti
service = default_service;
- return connect_to_this_ip46(protocol, socktype, host, scope_id, service, timeout);
+ return connect_to_this_ip46(protocol, socktype, host, scope_id, service, timeout,NULL);
}
void foreach_entry_in_connection_string(const char *destination, bool (*callback)(char *entry, void *data), void *data) {
diff --git a/src/libnetdata/socket/socket.h b/src/libnetdata/socket/socket.h
index 8eab8bfdd..8147c9774 100644
--- a/src/libnetdata/socket/socket.h
+++ b/src/libnetdata/socket/socket.h
@@ -33,7 +33,14 @@ int listen_sockets_setup(LISTEN_SOCKETS *sockets);
void listen_sockets_close(LISTEN_SOCKETS *sockets);
void foreach_entry_in_connection_string(const char *destination, bool (*callback)(char *entry, void *data), void *data);
-int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t scope_id, const char *service, struct timeval *timeout);
+int connect_to_this_ip46(
+ int protocol,
+ int socktype,
+ const char *host,
+ uint32_t scope_id,
+ const char *service,
+ struct timeval *timeout,
+ bool *fallback_ipv4);
int connect_to_this(const char *definition, int default_port, struct timeval *timeout);
int connect_to_one_of(const char *destination, int default_port, struct timeval *timeout, size_t *reconnects_counter, char *connected_to, size_t connected_to_size);
int connect_to_one_of_urls(const char *destination, int default_port, struct timeval *timeout, size_t *reconnects_counter, char *connected_to, size_t connected_to_size);
diff --git a/src/streaming/receiver.c b/src/streaming/receiver.c
index 50da031a7..0c0da2121 100644
--- a/src/streaming/receiver.c
+++ b/src/streaming/receiver.c
@@ -6,19 +6,6 @@
extern struct config stream_config;
void receiver_state_free(struct receiver_state *rpt) {
-
- freez(rpt->key);
- freez(rpt->hostname);
- freez(rpt->registry_hostname);
- freez(rpt->machine_guid);
- freez(rpt->os);
- freez(rpt->timezone);
- freez(rpt->abbrev_timezone);
- freez(rpt->client_ip);
- freez(rpt->client_port);
- freez(rpt->program_name);
- freez(rpt->program_version);
-
#ifdef ENABLE_HTTPS
netdata_ssl_close(&rpt->ssl);
#endif
@@ -31,10 +18,21 @@ void receiver_state_free(struct receiver_state *rpt) {
rrdpush_decompressor_destroy(&rpt->decompressor);
if(rpt->system_info)
- rrdhost_system_info_free(rpt->system_info);
+ rrdhost_system_info_free(rpt->system_info);
__atomic_sub_fetch(&netdata_buffers_statistics.rrdhost_receivers, sizeof(*rpt), __ATOMIC_RELAXED);
+ freez(rpt->key);
+ freez(rpt->hostname);
+ freez(rpt->registry_hostname);
+ freez(rpt->machine_guid);
+ freez(rpt->os);
+ freez(rpt->timezone);
+ freez(rpt->abbrev_timezone);
+ freez(rpt->client_ip);
+ freez(rpt->client_port);
+ freez(rpt->program_name);
+ freez(rpt->program_version);
freez(rpt);
}