diff options
Diffstat (limited to 'libnetdata/socket')
-rw-r--r-- | libnetdata/socket/README.md | 7 | ||||
-rw-r--r-- | libnetdata/socket/socket.c | 79 | ||||
-rw-r--r-- | libnetdata/socket/socket.h | 6 |
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); |