]> git.proxmox.com Git - mirror_corosync.git/blame - exec/totemudp.c
config: Don't free pointers used by transports
[mirror_corosync.git] / exec / totemudp.c
CommitLineData
5225b380
SD
1/*
2 * Copyright (c) 2005 MontaVista Software, Inc.
386d710e 3 * Copyright (c) 2006-2018 Red Hat, Inc.
5225b380
SD
4 *
5 * All rights reserved.
6 *
7 * Author: Steven Dake (sdake@redhat.com)
8
9 * This software licensed under BSD license, the text of which follows:
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * - Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * - Neither the name of the MontaVista Software, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include <config.h>
37
38#include <assert.h>
39#include <pthread.h>
40#include <sys/mman.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <sys/socket.h>
44#include <netdb.h>
45#include <sys/un.h>
46#include <sys/ioctl.h>
47#include <sys/param.h>
48#include <netinet/in.h>
49#include <arpa/inet.h>
50#include <unistd.h>
51#include <fcntl.h>
52#include <stdlib.h>
53#include <stdio.h>
54#include <errno.h>
55#include <sched.h>
56#include <time.h>
57#include <sys/time.h>
58#include <sys/poll.h>
932829bf 59#include <sys/uio.h>
5225b380
SD
60#include <limits.h>
61
62#include <corosync/sq.h>
c6895faa 63#include <corosync/swab.h>
f717bc60 64#include <qb/qbdefs.h>
fce8a3c3 65#include <qb/qbloop.h>
5225b380 66#define LOGSYS_UTILS_ONLY 1
8ad583a5 67#include <corosync/logsys.h>
5225b380 68#include "totemudp.h"
5225b380 69
00434a4f 70#include "util.h"
5225b380 71
5225b380
SD
72#ifndef MSG_NOSIGNAL
73#define MSG_NOSIGNAL 0
74#endif
75
76#define MCAST_SOCKET_BUFFER_SIZE (TRANSMITS_ALLOWED * FRAME_SIZE_MAX)
77#define NETIF_STATE_REPORT_UP 1
78#define NETIF_STATE_REPORT_DOWN 2
79
80#define BIND_STATE_UNBOUND 0
81#define BIND_STATE_REGULAR 1
82#define BIND_STATE_LOOPBACK 2
83
fc8580bd
CC
84struct totemudp_member {
85 struct qb_list_head list;
86 struct totem_ip_address member;
87};
88
5225b380
SD
89struct totemudp_socket {
90 int mcast_recv;
91 int mcast_send;
92 int token;
6c3b337b
JF
93 /*
94 * Socket used for local multicast delivery. We don't rely on multicast
95 * loop and rather this UNIX DGRAM socket is used. Socket is created by
96 * socketpair call and they are used in same way as pipe (so [0] is read
97 * end and [1] is write end)
98 */
99 int local_mcast_loop[2];
5225b380
SD
100};
101
102struct totemudp_instance {
fce8a3c3 103 qb_loop_t *totemudp_poll_handle;
5225b380
SD
104
105 struct totem_interface *totem_interface;
106
107 int netif_state_report;
108
109 int netif_bind_state;
110
5225b380
SD
111 void *context;
112
113 void (*totemudp_deliver_fn) (
114 void *context,
115 const void *msg,
69857efb
JF
116 unsigned int msg_len,
117 const struct sockaddr_storage *system_from);
5225b380
SD
118
119 void (*totemudp_iface_change_fn) (
120 void *context,
268cde6e
CC
121 const struct totem_ip_address *iface_address,
122 unsigned int ring_no);
5225b380 123
f9f663f4
SD
124 void (*totemudp_target_set_completed) (void *context);
125
5225b380
SD
126 /*
127 * Function and data used to log messages
128 */
129 int totemudp_log_level_security;
130
131 int totemudp_log_level_error;
132
133 int totemudp_log_level_warning;
134
135 int totemudp_log_level_notice;
136
137 int totemudp_log_level_debug;
138
139 int totemudp_subsys_id;
140
141 void (*totemudp_log_printf) (
37e17e7a
AS
142 int level,
143 int subsys,
5225b380
SD
144 const char *function,
145 const char *file,
146 int line,
147 const char *format,
37e17e7a 148 ...)__attribute__((format(printf, 6, 7)));
5225b380 149
5eae4c13 150 void *udp_context;
5225b380 151
fc8580bd
CC
152 struct qb_list_head member_list;
153
0f1813ad 154 char iov_buffer[UDP_RECEIVE_FRAME_SIZE_MAX];
5225b380 155
0f1813ad 156 char iov_buffer_flush[UDP_RECEIVE_FRAME_SIZE_MAX];
5225b380
SD
157
158 struct iovec totemudp_iov_recv;
159
160 struct iovec totemudp_iov_recv_flush;
161
162 struct totemudp_socket totemudp_sockets;
163
164 struct totem_ip_address mcast_address;
165
166 int stats_sent;
167
168 int stats_recv;
169
170 int stats_delv;
171
172 int stats_remcasts;
173
174 int stats_orf_token;
175
176 struct timeval stats_tv_start;
177
178 struct totem_ip_address my_id;
179
180 int firstrun;
181
fce8a3c3 182 qb_loop_timer_handle timer_netif_check_timeout;
5225b380
SD
183
184 unsigned int my_memb_entries;
185
186 int flushing;
187
188 struct totem_config *totem_config;
189
b7635ab9
JF
190 totemsrp_stats_t *stats;
191
5225b380
SD
192 struct totem_ip_address token_target;
193};
194
195struct work_item {
196 const void *msg;
197 unsigned int msg_len;
198 struct totemudp_instance *instance;
199};
200
5225b380
SD
201static int totemudp_build_sockets (
202 struct totemudp_instance *instance,
203 struct totem_ip_address *bindnet_address,
204 struct totem_ip_address *mcastaddress,
205 struct totemudp_socket *sockets,
206 struct totem_ip_address *bound_to);
207
208static struct totem_ip_address localhost;
209
5225b380
SD
210static void totemudp_instance_initialize (struct totemudp_instance *instance)
211{
212 memset (instance, 0, sizeof (struct totemudp_instance));
213
214 instance->netif_state_report = NETIF_STATE_REPORT_UP | NETIF_STATE_REPORT_DOWN;
215
216 instance->totemudp_iov_recv.iov_base = instance->iov_buffer;
217
0f1813ad 218 instance->totemudp_iov_recv.iov_len = UDP_RECEIVE_FRAME_SIZE_MAX; //sizeof (instance->iov_buffer);
5225b380
SD
219 instance->totemudp_iov_recv_flush.iov_base = instance->iov_buffer_flush;
220
0f1813ad 221 instance->totemudp_iov_recv_flush.iov_len = UDP_RECEIVE_FRAME_SIZE_MAX; //sizeof (instance->iov_buffer);
5225b380
SD
222
223 /*
224 * There is always atleast 1 processor
225 */
226 instance->my_memb_entries = 1;
fc8580bd
CC
227
228 qb_list_init (&instance->member_list);
5225b380
SD
229}
230
231#define log_printf(level, format, args...) \
232do { \
233 instance->totemudp_log_printf ( \
37e17e7a 234 level, instance->totemudp_subsys_id, \
5225b380
SD
235 __FUNCTION__, __FILE__, __LINE__, \
236 (const char *)format, ##args); \
237} while (0);
238
37e17e7a
AS
239#define LOGSYS_PERROR(err_num, level, fmt, args...) \
240do { \
241 char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
242 const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
243 instance->totemudp_log_printf ( \
244 level, instance->totemudp_subsys_id, \
245 __FUNCTION__, __FILE__, __LINE__, \
42a2f69e 246 fmt ": %s (%d)\n", ##args, _error_ptr, err_num); \
37e17e7a
AS
247 } while(0)
248
5eae4c13
SD
249int totemudp_crypto_set (
250 void *udp_context,
3b7c2f05
JF
251 const char *cipher_type,
252 const char *hash_type)
5225b380 253{
5225b380 254
42a2f69e 255 return (0);
5225b380
SD
256}
257
258
259static inline void ucast_sendmsg (
260 struct totemudp_instance *instance,
261 struct totem_ip_address *system_to,
262 const void *msg,
263 unsigned int msg_len)
264{
265 struct msghdr msg_ucast;
266 int res = 0;
5225b380
SD
267 struct sockaddr_storage sockaddr;
268 struct iovec iovec;
5225b380
SD
269 int addrlen;
270
268cde6e
CC
271 iovec.iov_base = (void*)msg;
272 iovec.iov_len = msg_len;
0a6a6bbc 273
5225b380
SD
274 /*
275 * Build unicast message
276 */
7026fffd 277 memset(&msg_ucast, 0, sizeof(msg_ucast));
5225b380
SD
278 totemip_totemip_to_sockaddr_convert(system_to,
279 instance->totem_interface->ip_port, &sockaddr, &addrlen);
280 msg_ucast.msg_name = &sockaddr;
281 msg_ucast.msg_namelen = addrlen;
55e84766
FDN
282 msg_ucast.msg_iov = (void *)&iovec;
283 msg_ucast.msg_iovlen = 1;
6d28d512 284#ifdef HAVE_MSGHDR_CONTROL
5225b380 285 msg_ucast.msg_control = 0;
6d28d512
FDN
286#endif
287#ifdef HAVE_MSGHDR_CONTROLLEN
5225b380 288 msg_ucast.msg_controllen = 0;
6d28d512
FDN
289#endif
290#ifdef HAVE_MSGHDR_FLAGS
5225b380 291 msg_ucast.msg_flags = 0;
6d28d512
FDN
292#endif
293#ifdef HAVE_MSGHDR_ACCRIGHTS
5225b380 294 msg_ucast.msg_accrights = NULL;
6d28d512
FDN
295#endif
296#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
5225b380
SD
297 msg_ucast.msg_accrightslen = 0;
298#endif
299
300
301 /*