diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/aclk/aclk.c | 8 | ||||
-rw-r--r-- | src/aclk/aclk_otp.c | 25 | ||||
-rw-r--r-- | src/aclk/aclk_otp.h | 6 | ||||
-rw-r--r-- | src/aclk/https_client.c | 7 | ||||
-rw-r--r-- | src/aclk/https_client.h | 2 | ||||
-rw-r--r-- | src/aclk/mqtt_websockets/mqtt_wss_client.c | 7 | ||||
-rw-r--r-- | src/aclk/mqtt_websockets/mqtt_wss_client.h | 10 | ||||
-rw-r--r-- | src/libnetdata/socket/socket.c | 18 | ||||
-rw-r--r-- | src/libnetdata/socket/socket.h | 9 |
9 files changed, 63 insertions, 29 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/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); |