summaryrefslogtreecommitdiffstats
path: root/libnetdata/socket
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/socket')
-rw-r--r--libnetdata/socket/README.md7
-rw-r--r--libnetdata/socket/socket.c79
-rw-r--r--libnetdata/socket/socket.h6
3 files changed, 66 insertions, 26 deletions
diff --git a/libnetdata/socket/README.md b/libnetdata/socket/README.md
index 70bfd344..e339a071 100644
--- a/libnetdata/socket/README.md
+++ b/libnetdata/socket/README.md
@@ -1,5 +1,8 @@
<!--
+Title: "Socket"
custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/socket/README.md
+sidebar_label: "Socket"
+learn_status: "Published"
+learn_topic_type: "References"
+learn_rel_path: "Developers/libnetdata"
-->
-
-
diff --git a/libnetdata/socket/socket.c b/libnetdata/socket/socket.c
index 69124b94..7eb212b3 100644
--- a/libnetdata/socket/socket.c
+++ b/libnetdata/socket/socket.c
@@ -1,5 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE // for POLLRDHUP
+#endif
+
+#ifndef __BSD_VISIBLE
+#define __BSD_VISIBLE // for POLLRDHUP
+#endif
+
#include "../libnetdata.h"
// --------------------------------------------------------------------------------------------------------------------
@@ -11,6 +19,46 @@
#define LARGE_SOCK_SIZE 4096
#endif
+bool fd_is_socket(int fd) {
+ int type;
+ socklen_t len = sizeof(type);
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) == -1)
+ return false;
+
+ return true;
+}
+
+bool sock_has_output_error(int fd) {
+ if(fd < 0) {
+ //internal_error(true, "invalid socket %d", fd);
+ return false;
+ }
+
+// if(!fd_is_socket(fd)) {
+// //internal_error(true, "fd %d is not a socket", fd);
+// return false;
+// }
+
+ short int errors = POLLERR | POLLHUP | POLLNVAL;
+
+#ifdef POLLRDHUP
+ errors |= POLLRDHUP;
+#endif
+
+ struct pollfd pfd = {
+ .fd = fd,
+ .events = POLLOUT | errors,
+ .revents = 0,
+ };
+
+ if(poll(&pfd, 1, 0) == -1) {
+ //internal_error(true, "poll() failed");
+ return false;
+ }
+
+ return ((pfd.revents & errors) || !(pfd.revents & POLLOUT));
+}
+
int sock_setnonblock(int fd) {
int flags;
@@ -923,53 +971,36 @@ int connect_to_one_of_urls(const char *destination, int default_port, struct tim
ssize_t netdata_ssl_read(SSL *ssl, void *buf, size_t num) {
error_limit_static_thread_var(erl, 1, 0);
- int bytes, err, retries = 0;
+ int bytes, err;
- //do {
bytes = SSL_read(ssl, buf, (int)num);
err = SSL_get_error(ssl, bytes);
- retries++;
- //} while (bytes <= 0 && err == SSL_ERROR_WANT_READ);
if(unlikely(bytes <= 0)) {
if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) {
bytes = 0;
} else
- error("SSL_write() returned %d bytes, SSL error %d", bytes, err);
+ error_limit(&erl, "SSL_write() returned %d bytes, SSL error %d", bytes, err);
}
- if(retries > 1)
- error_limit(&erl, "SSL_read() retried %d times", retries);
-
return bytes;
}
ssize_t netdata_ssl_write(SSL *ssl, const void *buf, size_t num) {
error_limit_static_thread_var(erl, 1, 0);
- int bytes, err, retries = 0;
- size_t total = 0;
+ int bytes, err;
- //do {
- bytes = SSL_write(ssl, (uint8_t *)buf + total, (int)(num - total));
+ bytes = SSL_write(ssl, (uint8_t *)buf, (int)num);
err = SSL_get_error(ssl, bytes);
- retries++;
-
- if(bytes > 0)
- total += bytes;
-
- //} while ((bytes <= 0 && (err == SSL_ERROR_WANT_WRITE)) || (bytes > 0 && total < num));
if(unlikely(bytes <= 0)) {
if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) {
bytes = 0;
} else
- error("SSL_write() returned %d bytes, SSL error %d", bytes, err);
+ error_limit(&erl, "SSL_write() returned %d bytes, SSL error %d", bytes, err);
}
- if(retries > 1)
- error_limit(&erl, "SSL_write() retried %d times", retries);
-
return bytes;
}
#endif
@@ -1118,8 +1149,8 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
* update the client_host if uninitialized - ensure the hostsize is the number
* of *writable* bytes (i.e. be aware of the strdup used to compact the pollinfo).
*/
-extern int connection_allowed(int fd, char *client_ip, char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list,
- const char *patname, int allow_dns)
+int connection_allowed(int fd, char *client_ip, char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list,
+ const char *patname, int allow_dns)
{
debug(D_LISTENER,"checking %s... (allow_dns=%d)", patname, allow_dns);
if (!access_list)
diff --git a/libnetdata/socket/socket.h b/libnetdata/socket/socket.h
index 9577453d..11006301 100644
--- a/libnetdata/socket/socket.h
+++ b/libnetdata/socket/socket.h
@@ -22,8 +22,11 @@ typedef enum web_client_acl {
WEB_CLIENT_ACL_SSL_FORCE = (1 << 7),
WEB_CLIENT_ACL_SSL_DEFAULT = (1 << 8),
WEB_CLIENT_ACL_ACLK = (1 << 9),
+ WEB_CLIENT_ACL_WEBRTC = (1 << 10),
} WEB_CLIENT_ACL;
+#define WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC (WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK | WEB_CLIENT_ACL_WEBRTC)
+
#define WEB_CLIENT_ACL_ALL 0xFFFF
#define web_client_can_access_dashboard(w) ((w)->acl & WEB_CLIENT_ACL_DASHBOARD)
@@ -74,6 +77,9 @@ ssize_t recv_timeout(int sockfd, void *buf, size_t len, int flags, int timeout);
ssize_t send_timeout(int sockfd, void *buf, size_t len, int flags, int timeout);
#endif
+bool fd_is_socket(int fd);
+bool sock_has_output_error(int fd);
+
int sock_setnonblock(int fd);
int sock_delnonblock(int fd);
int sock_setreuse(int fd, int reuse);