1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
// 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);
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);
#ifdef ENABLE_HTTPS
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);
#else
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);
int wait_on_socket_or_cancel_with_timeout(int fd, int timeout_ms, short int poll_events, short int *revents);
#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);
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 socket_peers {
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
|