]>
Commit | Line | Data |
---|---|---|
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 |
84 | struct totemudp_member { |
85 | struct qb_list_head list; | |
86 | struct totem_ip_address member; | |
87 | }; | |
88 | ||
5225b380 SD |
89 | struct 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 | ||
102 | struct 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 | ||
195 | struct work_item { | |
196 | const void *msg; | |
197 | unsigned int msg_len; | |
198 | struct totemudp_instance *instance; | |
199 | }; | |
200 | ||
5225b380 SD |
201 | static 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 | ||
208 | static struct totem_ip_address localhost; | |
209 | ||
5225b380 SD |
210 | static 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...) \ | |
232 | do { \ | |
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...) \ |
240 | do { \ | |
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 |
249 | int 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 | ||
259 | static 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 | /* | |