summaryrefslogtreecommitdiffstats
path: root/exporting/send_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'exporting/send_data.c')
-rw-r--r--exporting/send_data.c130
1 files changed, 129 insertions, 1 deletions
diff --git a/exporting/send_data.c b/exporting/send_data.c
index 8c579d8fce..f96c32bdee 100644
--- a/exporting/send_data.c
+++ b/exporting/send_data.c
@@ -45,6 +45,13 @@ void simple_connector_receive_response(int *sock, struct instance *instance)
response = buffer_create(1);
struct stats *stats = &instance->stats;
+#ifdef ENABLE_HTTPS
+ uint32_t options = (uint32_t)instance->config.options;
+ struct opentsdb_specific_data *connector_specific_data = instance->connector_specific_data;
+
+ if (options & EXPORTING_OPTION_USE_TLS)
+ ERR_clear_error();
+#endif
errno = 0;
@@ -53,7 +60,41 @@ void simple_connector_receive_response(int *sock, struct instance *instance)
buffer_need_bytes(response, 4096);
ssize_t r;
+#ifdef ENABLE_HTTPS
+ if (options & EXPORTING_OPTION_USE_TLS &&
+ connector_specific_data->conn &&
+ connector_specific_data->flags == NETDATA_SSL_HANDSHAKE_COMPLETE) {
+ r = (ssize_t)SSL_read(connector_specific_data->conn,
+ &response->buffer[response->len],
+ (int) (response->size - response->len));
+
+ if (likely(r > 0)) {
+ // we received some data
+ response->len += r;
+ stats->received_bytes += r;
+ stats->receptions++;
+ continue;
+ } else {
+ int sslerrno = SSL_get_error(connector_specific_data->conn, (int) r);
+ u_long sslerr = ERR_get_error();
+ char buf[256];
+ switch (sslerrno) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ goto endloop;
+ default:
+ ERR_error_string_n(sslerr, buf, sizeof(buf));
+ error("SSL error (%s)",
+ ERR_error_string((long)SSL_get_error(connector_specific_data->conn, (int)r), NULL));
+ goto endloop;
+ }
+ }
+ } else {
+ r = recv(*sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT);
+ }
+#else
r = recv(*sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT);
+#endif
if (likely(r > 0)) {
// we received some data
response->len += r;
@@ -69,10 +110,14 @@ void simple_connector_receive_response(int *sock, struct instance *instance)
error("EXPORTING: cannot receive data from '%s'.", instance->config.destination);
}
}
+
#ifdef UNIT_TESTING
break;
#endif
}
+#ifdef ENABLE_HTTPS
+endloop:
+#endif
// if we received data, process them
if (buffer_strlen(response))
@@ -96,6 +141,14 @@ void simple_connector_send_buffer(int *sock, int *failures, struct instance *ins
flags += MSG_NOSIGNAL;
#endif
+#ifdef ENABLE_HTTPS
+ uint32_t options = (uint32_t)instance->config.options;
+ struct opentsdb_specific_data *connector_specific_data = instance->connector_specific_data;
+
+ if (options & EXPORTING_OPTION_USE_TLS)
+ ERR_clear_error();
+#endif
+
struct stats *stats = &instance->stats;
int ret = 0;
@@ -104,8 +157,19 @@ void simple_connector_send_buffer(int *sock, int *failures, struct instance *ins
ssize_t written = -1;
- if (!ret)
+ if (!ret) {
+#ifdef ENABLE_HTTPS
+ if (options & EXPORTING_OPTION_USE_TLS &&
+ connector_specific_data->conn &&
+ connector_specific_data->flags == NETDATA_SSL_HANDSHAKE_COMPLETE) {
+ written = (ssize_t)SSL_write(connector_specific_data->conn, buffer_tostring(buffer), len);
+ } else {
+ written = send(*sock, buffer_tostring(buffer), len, flags);
+ }
+#else
written = send(*sock, buffer_tostring(buffer), len, flags);
+#endif
+ }
if(written != -1 && (size_t)written == len) {
// we sent the data successfully
@@ -167,6 +231,13 @@ void simple_connector_worker(void *instance_p)
{
struct instance *instance = (struct instance*)instance_p;
+#ifdef ENABLE_HTTPS
+ uint32_t options = (uint32_t)instance->config.options;
+ struct opentsdb_specific_data *connector_specific_data = instance->connector_specific_data;
+
+ if (options & EXPORTING_OPTION_USE_TLS)
+ ERR_clear_error();
+#endif
struct simple_connector_config *connector_specific_config = instance->config.connector_specific_config;
struct stats *stats = &instance->stats;
@@ -208,6 +279,56 @@ void simple_connector_worker(void *instance_p)
&reconnects,
NULL,
0);
+#ifdef ENABLE_HTTPS
+ if(sock != -1) {
+ if (netdata_opentsdb_ctx) {
+ if ( sock_delnonblock(sock) < 0 )
+ error("Exporting cannot remove the non-blocking flag from socket %d", sock);
+
+ if (connector_specific_data->conn == NULL) {
+ connector_specific_data->conn = SSL_new(netdata_opentsdb_ctx);
+ if (connector_specific_data->conn == NULL) {
+ error("Failed to allocate SSL structure to socket %d.", sock);
+ connector_specific_data->flags = NETDATA_SSL_NO_HANDSHAKE;
+ }
+ } else {
+ SSL_clear(connector_specific_data->conn);
+ }
+
+ if (connector_specific_data->conn) {
+ if (SSL_set_fd(connector_specific_data->conn, sock) != 1) {
+ error("Failed to set the socket to the SSL on socket fd %d.", sock);
+ connector_specific_data->flags = NETDATA_SSL_NO_HANDSHAKE;
+ } else {
+ connector_specific_data->flags = NETDATA_SSL_HANDSHAKE_COMPLETE;
+ SSL_set_connect_state(connector_specific_data->conn);
+ int err = SSL_connect(connector_specific_data->conn);
+ if (err != 1) {
+ err = SSL_get_error(connector_specific_data->conn, err);
+ error("SSL cannot connect with the server: %s ",
+ ERR_error_string((long)SSL_get_error(connector_specific_data->conn, err), NULL));
+ connector_specific_data->flags = NETDATA_SSL_NO_HANDSHAKE;
+ } else {
+ info("Exporting established a SSL connection.");
+
+ struct timeval tv;
+ tv.tv_sec = timeout.tv_sec /4;
+ tv.tv_usec = 0;
+
+ if (!tv.tv_sec)
+ tv.tv_sec = 2;
+
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)))
+ error("Cannot set timeout to socket %d, this can block communication", sock);
+
+ }
+ }
+ }
+ }
+
+ }
+#endif
+
stats->reconnects += reconnects;
}
@@ -265,5 +386,12 @@ void simple_connector_worker(void *instance_p)
clean_prometheus_remote_write(instance);
#endif
+#ifdef ENABLE_HTTPS
+ if (options & EXPORTING_OPTION_USE_TLS) {
+ SSL_free(connector_specific_data->conn);
+ freez(instance->connector_specific_data);
+ }
+#endif
+
simple_connector_cleanup(instance);
}