// SPDX-License-Identifier: GPL-3.0-or-later #ifndef NETDATA_SOCKET_H #define NETDATA_SOCKET_H #include "../libnetdata.h" #ifndef MAX_LISTEN_FDS #define MAX_LISTEN_FDS 50 #endif #define ND_CHECK_CANCELLABILITY_WHILE_WAITING_EVERY_MS 100 typedef struct listen_sockets { struct config *config; // the config file to use const char *config_section; // the netdata configuration section to read settings from const char *default_bind_to; // the default bind to configuration string uint16_t default_port; // the default port to use int backlog; // the default listen backlog to use size_t opened; // the number of sockets opened size_t failed; // the number of sockets attempted to open, but failed int fds[MAX_LISTEN_FDS]; // the open sockets char *fds_names[MAX_LISTEN_FDS]; // descriptions for the open sockets int fds_types[MAX_LISTEN_FDS]; // the socktype for the open sockets (SOCK_STREAM, SOCK_DGRAM) int fds_families[MAX_LISTEN_FDS]; // the family of the open sockets (AF_UNIX, AF_INET, AF_INET6) HTTP_ACL fds_acl_flags[MAX_LISTEN_FDS]; // the acl to apply to the open sockets (dashboard, badges, streaming, netdata.conf, management) } LISTEN_SOCKETS; char *strdup_client_description(int family, const char *protocol, const char *ip, uint16_t port); 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, 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); ssize_t recv_timeout(NETDATA_SSL *ssl,int sockfd, void *buf, size_t len, int flags, int timeout); ssize_t send_timeout(NETDATA_SSL *ssl,int sockfd, void *buf, size_t len, int flags, int timeout); int wait_on_socket_or_cancel_with_timeout(NETDATA_SSL *ssl, int fd, int timeout_ms, short int poll_events, short int *revents); bool fd_is_socket(int fd); bool is_socket_closed(int fd); int sock_setnonblock(int fd); int sock_delnonblock(int fd); int sock_setreuse(int fd, int reuse); void sock_setcloexec(int fd); int sock_setreuse_port(int fd, int reuse); int sock_enlarge_in(int fd); int sock_enlarge_out(int fd); 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 accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize, char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list, int allow_dns); #ifndef HAVE_ACCEPT4 int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags); #endif /* #ifndef HAVE_ACCEPT4 */ #ifdef SOCK_CLOEXEC #define DEFAULT_SOCKET_FLAGS SOCK_CLOEXEC #else #define DEFAULT_SOCKET_FLAGS 0 #endif // ---------------------------------------------------------------------------- // poll() based listener #define POLLINFO_FLAG_SERVER_SOCKET 0x00000001 #define POLLINFO_FLAG_CLIENT_SOCKET 0x00000002 #define POLLINFO_FLAG_DONT_CLOSE 0x00000004 typedef struct poll POLLJOB; typedef struct pollinfo { POLLJOB *p; // the parent size_t slot; // the slot id int fd; // the file descriptor int socktype; // the client socket type HTTP_ACL port_acl; // the access lists permitted on this web server port (it's -1 for client sockets) char *client_ip; // Max INET6_ADDRSTRLEN bytes char *client_port; // Max NI_MAXSERV bytes char *client_host; // Max NI_MAXHOST bytes time_t connected_t; // the time the socket connected time_t last_received_t; // the time the socket last received data time_t last_sent_t; // the time the socket last sent data size_t recv_count; // the number of times the socket was ready for inbound traffic size_t send_count; // the number of times the socket was ready for outbound traffic uint32_t flags; // internal flags // callbacks for this socket void (*del_callback)(struct pollinfo *pi); int (*rcv_callback)(struct pollinfo *pi, short int *events); int (*snd_callback)(struct pollinfo *pi, short int *events); // the user data void *data; // linking of free pollinfo structures // for quickly finding the next available // this is like a stack, it grows and shrinks // (with gaps - lower empty slots are preferred) struct pollinfo *next; } POLLINFO; struct poll { size_t slots; size_t used; size_t min; size_t max; size_t limit; time_t complete_request_timeout; time_t idle_timeout; time_t checks_every; time_t timer_milliseconds; void *timer_data; struct pollfd *fds; struct pollinfo *inf; struct pollinfo *first_free; SIMPLE_PATTERN *access_list; int allow_dns; void *(*add_callback)(POLLINFO *pi, short int *events, void *data); void (*del_callback)(POLLINFO *pi); int (*rcv_callback)(POLLINFO *pi, short int *events); int (*snd_callback)(POLLINFO *pi, short int *events); void (*tmr_callback)(void *timer_data); }; #define pollinfo_from_slot(p, slot) (&((p)->inf[(slot)])) int poll_default_snd_callback(POLLINFO *pi, short int *events); int poll_default_rcv_callback(POLLINFO *pi, short int *events); void poll_default_del_callback(POLLINFO *pi); void *poll_default_add_callback(POLLINFO *pi, short int *events, void *data); POLLINFO *poll_add_fd(POLLJOB *p , int fd , int socktype , HTTP_ACL port_acl , uint32_t flags , const char *client_ip , const char *client_port , const char *client_host , void *(*add_callback)(POLLINFO *pi, short int *events, void *data) , void (*del_callback)(POLLINFO *pi) , int (*rcv_callback)(POLLINFO *pi, short int *events) , int (*snd_callback)(POLLINFO *pi, short int *events) , void *data ); void poll_close_fd(POLLINFO *pi); void poll_events(LISTEN_SOCKETS *sockets , void *(*add_callback)(POLLINFO *pi, short int *events, void *data) , void (*del_callback)(POLLINFO *pi) , int (*rcv_callback)(POLLINFO *pi, short int *events) , int (*snd_callback)(POLLINFO *pi, short int *events) , void (*tmr_callback)(void *timer_data) , bool (*check_to_stop_callback)(void) , SIMPLE_PATTERN *access_list , int allow_dns , void *data , time_t tcp_request_timeout_seconds , time_t tcp_idle_timeout_seconds , time_t timer_milliseconds , void *timer_data , size_t max_tcp_sockets ); #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 46 #endif typedef struct { struct { char ip[INET6_ADDRSTRLEN]; int port; } local; struct { char ip[INET6_ADDRSTRLEN]; int port; } peer; } SOCKET_PEERS; SOCKET_PEERS socket_peers(int sock_fd); bool ip_to_hostname(const char *ip, char *dst, size_t dst_len); #endif //NETDATA_SOCKET_H