1/*
2 * socket.h
3 *
4 * Copyright (C) 2008-2018 Aerospike, Inc.
5 *
6 * Portions may be licensed to Aerospike, Inc. under one or more contributor
7 * license agreements.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Affero General Public License as published by the Free
11 * Software Foundation, either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see http://www.gnu.org/licenses/
21 */
22
23#pragma once
24
25#include <alloca.h>
26#include <stdbool.h>
27#include <stddef.h>
28#include <stdint.h>
29
30#include <netinet/in.h>
31#include <sys/epoll.h>
32#include <sys/socket.h>
33
34#include "dns.h"
35#include "fault.h"
36#include "msg.h"
37#include "node.h"
38
39// Use forward declaration instead of including openssl/ssl.h here.
40struct ssl_st;
41
42#define CF_SOCKET_TIMEOUT 10000
43#define CF_SOCK_CFG_MAX 250
44
45// Accesses the socket file descriptor as an rvalue, i.e., the socket file descriptor
46// cannot be modified.
47#define CSFD(sock) ((int32_t)((sock)->fd))
48
49// CSFD() for epoll file descriptors.
50#define CEFD(poll) ((int32_t)(poll).fd)
51
52// Like CEFD(), but produces an lvalue, i.e., the epoll file descriptor can be modified.
53#define EFD(poll) ((poll).fd)
54
55#define INVALID_POLL ((cf_poll){ .fd = -1 })
56
57#define cf_ip_addr_print(_addr) ({ \
58 char *_tmp = alloca(250); \
59 cf_ip_addr_to_string_safe(_addr, _tmp, 250); \
60 _tmp; \
61})
62
63#define cf_ip_addr_print_multi(_addrs, _n_addrs) ({ \
64 char *_tmp = alloca(2500); \
65 cf_ip_addr_to_string_multi_safe(_addrs, _n_addrs, _tmp, 2500); \
66 _tmp; \
67})
68
69#define cf_ip_port_print(_port) ({ \
70 char *_tmp = alloca(25); \
71 cf_ip_port_to_string_safe(_port, _tmp, 25); \
72 _tmp; \
73})
74
75#define cf_sock_addr_print(_addr) ({ \
76 char *_tmp = alloca(250); \
77 cf_sock_addr_to_string_safe(_addr, _tmp, 250); \
78 _tmp; \
79})
80
81typedef struct cf_ip_addr_s {
82 sa_family_t family;
83
84 union {
85 struct in_addr v4;
86 struct in6_addr v6;
87 };
88} cf_ip_addr;
89
90typedef struct cf_ip_net_s {
91 sa_family_t family;
92
93 union {
94 struct in_addr v4;
95 struct in6_addr v6;
96 } addr;
97
98 union {
99 struct in_addr v4;
100 struct in6_addr v6;
101 } mask;
102} cf_ip_net;
103
104typedef uint16_t cf_ip_port;
105
106typedef struct cf_addr_list_s {
107 uint32_t n_addrs;
108 const char *addrs[CF_SOCK_CFG_MAX];
109} cf_addr_list;
110
111typedef struct cf_serv_spec_s {
112 cf_ip_port bind_port;
113 cf_addr_list bind;
114 cf_ip_port std_port;
115 cf_addr_list std;
116 cf_ip_port alt_port;
117 cf_addr_list alt;
118 char *tls_our_name;
119 uint32_t n_tls_peer_names;
120 char *tls_peer_names[CF_SOCK_CFG_MAX];
121} cf_serv_spec;
122
123typedef struct cf_sock_addr_s {
124 cf_ip_addr addr;
125 cf_ip_port port;
126} cf_sock_addr;
127
128typedef enum {
129 CF_SOCKET_STATE_NON_TLS,
130 CF_SOCKET_STATE_TLS_HANDSHAKE,
131 CF_SOCKET_STATE_TLS_READY
132} cf_socket_state;
133
134typedef struct cf_socket_s {
135 int32_t fd;
136 cf_socket_state state;
137 void *cfg;
138 struct ssl_st *ssl;
139} cf_socket;
140
141typedef struct cf_sockets_s {
142 uint32_t n_socks;
143 cf_socket socks[CF_SOCK_CFG_MAX];
144} cf_sockets;
145
146typedef enum {
147 CF_SOCK_OWNER_SERVICE,
148 CF_SOCK_OWNER_SERVICE_TLS,
149 CF_SOCK_OWNER_HEARTBEAT,
150 CF_SOCK_OWNER_HEARTBEAT_TLS,
151 CF_SOCK_OWNER_FABRIC,
152 CF_SOCK_OWNER_FABRIC_TLS,
153 CF_SOCK_OWNER_INFO,
154 CF_SOCK_OWNER_XDR,
155 CF_SOCK_OWNER_INVALID
156} cf_sock_owner;
157
158typedef struct cf_sock_cfg_s {
159 cf_sock_owner owner;
160 cf_ip_port port;
161 cf_ip_addr addr;
162} cf_sock_cfg;
163
164typedef struct cf_serv_cfg_s {
165 uint32_t n_cfgs;
166 cf_sock_cfg cfgs[CF_SOCK_CFG_MAX];
167} cf_serv_cfg;
168
169typedef struct cf_poll_s {
170 int32_t fd;
171} __attribute__((packed)) cf_poll;
172
173// This precisely matches the epoll_event struct.
174typedef struct cf_poll_event_s {
175 uint32_t events;
176 void *data;
177} __attribute__((packed)) cf_poll_event;
178
179typedef struct cf_msock_cfg_s {
180 cf_sock_owner owner;
181 cf_ip_port port;
182 cf_ip_addr addr;
183 cf_ip_addr if_addr;
184 uint8_t ttl;
185} cf_msock_cfg;
186
187typedef struct cf_mserv_cfg_s {
188 uint32_t n_cfgs;
189 cf_msock_cfg cfgs[CF_SOCK_CFG_MAX];
190} cf_mserv_cfg;
191
192typedef void (*cf_ip_addr_from_string_cb)(bool is_resolved, const char* name, const cf_ip_addr *addrs, const uint32_t n_addrs, void *udata);
193
194void cf_socket_set_advertise_ipv6(bool advertise);
195bool cf_socket_advertises_ipv6(void);
196
197CF_MUST_CHECK int32_t cf_ip_addr_from_string(const char *string, cf_ip_addr *addr);
198CF_MUST_CHECK int32_t cf_ip_addr_from_string_multi(const char *string, cf_ip_addr *addrs, uint32_t *n_addrs);
199void cf_ip_addr_from_string_multi_a(const char *string, cf_ip_addr_from_string_cb cb, void *udata);
200CF_MUST_CHECK int32_t cf_ip_addr_to_string(const cf_ip_addr *addr, char *string, size_t size);
201void cf_ip_addr_to_string_safe(const cf_ip_addr *addr, char *string, size_t size);
202CF_MUST_CHECK int32_t cf_ip_addr_to_string_multi(const cf_ip_addr *addrs, uint32_t n_addrs, char *string, size_t size);
203void cf_ip_addr_to_string_multi_safe(const cf_ip_addr *addrs, uint32_t n_addrs, char *string, size_t size);
204CF_MUST_CHECK int32_t cf_ip_addr_from_binary(const uint8_t *binary, size_t size, cf_ip_addr *addr);
205CF_MUST_CHECK int32_t cf_ip_addr_to_binary(const cf_ip_addr *addr, uint8_t *binary, size_t size);
206void cf_ip_addr_to_rack_aware_id(const cf_ip_addr *addr, uint32_t *id);
207
208CF_MUST_CHECK int32_t cf_ip_addr_compare(const cf_ip_addr *lhs, const cf_ip_addr *rhs);
209void cf_ip_addr_copy(const cf_ip_addr *from, cf_ip_addr *to);
210void cf_ip_addr_sort(cf_ip_addr *addrs, uint32_t n_addrs);
211
212bool cf_ip_addr_is_dns_name(const char *string);
213bool cf_ip_addr_str_is_legacy(const char *string);
214bool cf_ip_addr_is_legacy(const cf_ip_addr *addr);
215bool cf_ip_addr_legacy_only(void);
216
217void cf_ip_addr_set_local(cf_ip_addr *addr);
218CF_MUST_CHECK bool cf_ip_addr_is_local(const cf_ip_addr *addr);
219
220void cf_ip_addr_set_any(cf_ip_addr *addr);
221CF_MUST_CHECK bool cf_ip_addr_is_any(const cf_ip_addr *addr);
222
223CF_MUST_CHECK int32_t cf_ip_net_from_string(const char *string, cf_ip_net *net);
224CF_MUST_CHECK int32_t cf_ip_net_to_string(const cf_ip_net *net, char *string, size_t size);
225CF_MUST_CHECK bool cf_ip_net_contains(const cf_ip_net *net, const cf_ip_addr *addr);
226
227CF_MUST_CHECK int32_t cf_ip_port_from_string(const char *string, cf_ip_port *port);
228CF_MUST_CHECK int32_t cf_ip_port_to_string(cf_ip_port port, char *string, size_t size);
229void cf_ip_port_to_string_safe(cf_ip_port port, char *string, size_t size);
230CF_MUST_CHECK int32_t cf_ip_port_from_binary(const uint8_t *binary, size_t size, cf_ip_port *port);
231CF_MUST_CHECK int32_t cf_ip_port_to_binary(cf_ip_port port, uint8_t *binary, size_t size);
232void cf_ip_port_from_node_id(cf_node id, cf_ip_port *port);
233
234CF_MUST_CHECK int32_t cf_sock_addr_from_string(const char *string, cf_sock_addr *addr);
235CF_MUST_CHECK int32_t cf_sock_addr_to_string(const cf_sock_addr *addr, char *string, size_t size);
236void cf_sock_addr_to_string_safe(const cf_sock_addr *addr, char *string, size_t size);
237CF_MUST_CHECK int32_t cf_sock_addr_from_binary(const uint8_t *binary, size_t size, cf_sock_addr *addr);
238CF_MUST_CHECK int32_t cf_sock_addr_to_binary(const cf_sock_addr *addr, uint8_t *binary, size_t size);
239
240CF_MUST_CHECK int32_t cf_sock_addr_from_host_port(const char *host, cf_ip_port port, cf_sock_addr *addr);
241void cf_sock_addr_from_addr_port(const cf_ip_addr *ip_addr, cf_ip_port port, cf_sock_addr *addr);
242
243CF_MUST_CHECK int32_t cf_sock_addr_compare(const cf_sock_addr *lhs, const cf_sock_addr *rhs);
244void cf_sock_addr_copy(const cf_sock_addr *from, cf_sock_addr *to);
245
246void cf_sock_addr_from_native(const struct sockaddr *native, cf_sock_addr *addr);
247void cf_sock_addr_to_native(const cf_sock_addr *addr, struct sockaddr *native);
248
249void cf_sock_addr_set_any(cf_sock_addr *addr);
250CF_MUST_CHECK bool cf_sock_addr_is_any(const cf_sock_addr *addr);
251
252void cf_sock_cfg_init(cf_sock_cfg *cfg, cf_sock_owner owner);
253void cf_sock_cfg_copy(const cf_sock_cfg *from, cf_sock_cfg *to);
254
255void cf_serv_cfg_init(cf_serv_cfg *cfg);
256CF_MUST_CHECK int32_t cf_serv_cfg_add_sock_cfg(cf_serv_cfg *serv_cfg, const cf_sock_cfg *sock_cfg);
257
258void cf_sockets_init(cf_sockets *socks);
259CF_MUST_CHECK bool cf_sockets_has_socket(const cf_sockets *socks, const cf_socket *sock);
260void cf_sockets_close(cf_sockets *socks);
261
262void cf_fd_disable_blocking(int32_t fd);
263
264void cf_socket_disable_blocking(cf_socket *sock);
265void cf_socket_enable_blocking(cf_socket *sock);
266void cf_socket_disable_nagle(cf_socket *sock);
267void cf_socket_enable_nagle(cf_socket *sock);
268void cf_socket_set_cork(cf_socket *sock, int cork);
269void cf_socket_keep_alive(cf_socket *sock, int32_t idle, int32_t interval, int32_t count);
270void cf_socket_set_send_buffer(cf_socket *sock, int32_t size);
271void cf_socket_set_receive_buffer(cf_socket *sock, int32_t size);
272void cf_socket_set_window(cf_socket *sock, int32_t size);
273
274void cf_socket_init(cf_socket *sock);
275bool cf_socket_exists(cf_socket *sock);
276
277static inline void cf_socket_copy(const cf_socket *from, cf_socket *to)
278{
279 to->fd = from->fd;
280 to->state = from->state;
281 to->cfg = from->cfg;
282 to->ssl = from->ssl;
283}
284
285CF_MUST_CHECK int32_t cf_socket_init_server(cf_serv_cfg *cfg, cf_sockets *socks);
286void cf_socket_show_server(cf_fault_context cont, const char *tag, const cf_sockets *socks);
287CF_MUST_CHECK int32_t cf_socket_init_client(cf_sock_cfg *cfg, int32_t timeout, cf_socket *sock);
288
289CF_MUST_CHECK int32_t cf_socket_accept(cf_socket *lsock, cf_socket *sock, cf_sock_addr *addr);
290CF_MUST_CHECK int32_t cf_socket_remote_name(const cf_socket *sock, cf_sock_addr *addr);
291CF_MUST_CHECK int32_t cf_socket_local_name(const cf_socket *sock, cf_sock_addr *addr);
292CF_MUST_CHECK int32_t cf_socket_available(cf_socket *sock);
293
294CF_MUST_CHECK int32_t cf_socket_recv_from(cf_socket *sock, void *buff, size_t size, int32_t flags, cf_sock_addr *addr);
295CF_MUST_CHECK int32_t cf_socket_recv(cf_socket *sock, void *buff, size_t size, int32_t flags);
296CF_MUST_CHECK int32_t cf_socket_recv_msg(cf_socket *sock, struct msghdr *m, int32_t flags);
297CF_MUST_CHECK int32_t cf_socket_send_to(cf_socket *sock, const void *buff, size_t size, int32_t flags, const cf_sock_addr *addr);
298CF_MUST_CHECK int32_t cf_socket_send(cf_socket *sock, const void *buff, size_t size, int32_t flags);
299CF_MUST_CHECK int32_t cf_socket_send_msg(cf_socket *sock, struct msghdr *m, int32_t flags);
300
301CF_MUST_CHECK int32_t cf_socket_recv_all(cf_socket *sock, void *buff, size_t size, int32_t flags, int32_t timeout);
302CF_MUST_CHECK int32_t cf_socket_send_all(cf_socket *sock, const void *buff, size_t size, int32_t flags, int32_t timeout);
303CF_MUST_CHECK int32_t cf_socket_try_send_all(cf_socket *sock, const void *buff, size_t size, int32_t flags);
304
305void cf_socket_write_shutdown(cf_socket *sock);
306void cf_socket_shutdown(cf_socket *sock);
307void cf_socket_close(cf_socket *sock);
308void cf_socket_drain_close(cf_socket *sock);
309void cf_socket_term(cf_socket *sock);
310
311void cf_msock_cfg_init(cf_msock_cfg *cfg, cf_sock_owner owner);
312void cf_msock_cfg_copy(const cf_msock_cfg *from, cf_msock_cfg *to);
313
314void cf_mserv_cfg_init(cf_mserv_cfg *cfg);
315CF_MUST_CHECK int32_t cf_mserv_cfg_add_msock_cfg(cf_mserv_cfg *serv_cfg, const cf_msock_cfg *sock_cfg);
316CF_MUST_CHECK int32_t cf_mserv_cfg_add_combo(cf_mserv_cfg *serv_cfg, cf_sock_owner owner, cf_ip_port port, cf_ip_addr *addr, cf_ip_addr *if_addr, uint8_t ttl);
317
318CF_MUST_CHECK int32_t cf_socket_mcast_init(cf_mserv_cfg *cfg, cf_sockets *socks);
319void cf_socket_mcast_show(cf_fault_context cont, const char *tag, const cf_sockets *socks);
320CF_MUST_CHECK int32_t cf_socket_mcast_set_inter(cf_socket *sock, const cf_ip_addr *iaddr);
321CF_MUST_CHECK int32_t cf_socket_mcast_set_ttl(cf_socket *sock, int32_t ttl);
322CF_MUST_CHECK int32_t cf_socket_mcast_join_group(cf_socket *sock, const cf_ip_addr *iaddr, const cf_ip_addr *gaddr);
323
324void cf_poll_create(cf_poll *poll);
325
326static inline bool cf_poll_equal(const cf_poll poll1, const cf_poll poll2)
327{
328 return CEFD(poll1) == CEFD(poll2);
329}
330
331void cf_poll_add_fd(cf_poll poll, int32_t fd, uint32_t events, void *data);
332void cf_poll_add_socket(cf_poll poll, const cf_socket *sock, uint32_t events, void *data);
333CF_MUST_CHECK int32_t cf_poll_modify_socket_forgiving(cf_poll poll, const cf_socket *sock, uint32_t events, void *data, uint32_t n_err_ok, const int32_t *err_ok);
334CF_MUST_CHECK int32_t cf_poll_delete_socket_forgiving(cf_poll poll, const cf_socket *sock, uint32_t n_err_ok, int32_t *err_ok);
335void cf_poll_add_sockets(cf_poll poll, cf_sockets *socks, uint32_t events);
336void cf_poll_delete_sockets(cf_poll poll, cf_sockets *socks);
337CF_MUST_CHECK int32_t cf_poll_wait(cf_poll poll, cf_poll_event *events, int32_t limit, int32_t timeout);
338void cf_poll_destroy(cf_poll poll);
339
340static inline void cf_poll_modify_socket(cf_poll poll, const cf_socket *sock, uint32_t events, void *data)
341{
342 CF_IGNORE_ERROR(cf_poll_modify_socket_forgiving(poll, sock, events, data, 0, NULL));
343}
344
345static inline void cf_poll_delete_socket(cf_poll poll, const cf_socket *sock)
346{
347 CF_IGNORE_ERROR(cf_poll_delete_socket_forgiving(poll, sock, 0, NULL));
348}
349
350CF_MUST_CHECK int32_t cf_inter_get_addr_all(cf_ip_addr *addrs, uint32_t *n_addrs);
351CF_MUST_CHECK int32_t cf_inter_get_addr_all_legacy(cf_ip_addr *addrs, uint32_t *n_addrs);
352CF_MUST_CHECK int32_t cf_inter_get_addr_def(cf_ip_addr *addrs, uint32_t *n_addrs);
353CF_MUST_CHECK int32_t cf_inter_get_addr_def_legacy(cf_ip_addr *addrs, uint32_t *n_addrs);
354CF_MUST_CHECK int32_t cf_inter_get_addr_name(cf_ip_addr *addrs, uint32_t *n_addrs, const char *if_name);
355bool cf_inter_is_inter_name(const char *if_name);
356CF_MUST_CHECK int32_t cf_inter_addr_to_index_and_name(const cf_ip_addr *addr, int32_t *index, char **name);
357CF_MUST_CHECK int32_t cf_inter_get_physical(const char *if_name, char *phys_name, uint32_t phys_name_sz);
358void cf_inter_expand_bond(const char *if_name, char **out_names, uint32_t *n_out);
359CF_MUST_CHECK int32_t cf_inter_mtu(const cf_ip_addr *inter_addr);
360CF_MUST_CHECK int32_t cf_inter_min_mtu(void);
361bool cf_inter_detect_changes(cf_ip_addr *addrs, uint32_t *n_addrs, uint32_t limit);
362bool cf_inter_detect_changes_legacy(cf_ip_addr *addrs, uint32_t *n_addrs, uint32_t limit);
363
364CF_MUST_CHECK int32_t cf_node_id_get(cf_ip_port port, const char *if_hint, cf_node *id);
365
366#if defined CF_SOCKET_PRIVATE
367CF_MUST_CHECK size_t cf_socket_addr_len(const struct sockaddr* sa);
368CF_MUST_CHECK int32_t cf_socket_parse_netlink(bool allow_v6, uint32_t family, uint32_t flags,
369 const void *data, size_t len, cf_ip_addr *addr);
370void cf_socket_fix_client(cf_socket *sock);
371void cf_socket_fix_bind(cf_serv_cfg *serv_cfg);
372void cf_socket_fix_server(cf_socket *sock);
373
374extern addrinfo g_cf_ip_addr_dns_hints;
375CF_MUST_CHECK int32_t cf_ip_addr_from_addrinfo(const char *name, const addrinfo *info, cf_ip_addr *addrs, uint32_t *n_addrs);
376#endif
377