corosync  3.1.0
totemudpu.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005 MontaVista Software, Inc.
3  * Copyright (c) 2006-2018 Red Hat, Inc.
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 <sys/mman.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/socket.h>
43 #include <netdb.h>
44 #include <sys/un.h>
45 #include <sys/ioctl.h>
46 #include <sys/param.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49 #include <unistd.h>
50 #include <fcntl.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <errno.h>
54 #include <sched.h>
55 #include <time.h>
56 #include <sys/time.h>
57 #include <sys/poll.h>
58 #include <sys/uio.h>
59 #include <limits.h>
60 
61 #include <qb/qblist.h>
62 #include <qb/qbdefs.h>
63 #include <qb/qbloop.h>
64 
65 #include <corosync/sq.h>
66 #include <corosync/swab.h>
67 #define LOGSYS_UTILS_ONLY 1
68 #include <corosync/logsys.h>
69 #include "totemudpu.h"
70 
71 #include "util.h"
72 
73 #ifndef MSG_NOSIGNAL
74 #define MSG_NOSIGNAL 0
75 #endif
76 
77 #define MCAST_SOCKET_BUFFER_SIZE (TRANSMITS_ALLOWED * UDP_RECEIVE_FRAME_SIZE_MAX)
78 #define NETIF_STATE_REPORT_UP 1
79 #define NETIF_STATE_REPORT_DOWN 2
80 
81 #define BIND_STATE_UNBOUND 0
82 #define BIND_STATE_REGULAR 1
83 #define BIND_STATE_LOOPBACK 2
84 
86  struct qb_list_head list;
87  struct totem_ip_address member;
88  int fd;
89  int active;
90 };
91 
94 
96 
98 
100 
101  void *context;
102 
104  void *context,
105  const void *msg,
106  unsigned int msg_len,
107  const struct sockaddr_storage *system_from);
108 
110  void *context,
111  const struct totem_ip_address *iface_address,
112  unsigned int ring_no);
113 
115 
116  /*
117  * Function and data used to log messages
118  */
120 
122 
124 
126 
128 
130 
132  int level,
133  int subsys,
134  const char *function,
135  const char *file,
136  int line,
137  const char *format,
138  ...)__attribute__((format(printf, 6, 7)));
139 
141 
143 
144  struct iovec totemudpu_iov_recv;
145 
146  struct qb_list_head member_list;
147 
149 
151 
153 
155 
157 
158  struct timeval stats_tv_start;
159 
160  struct totem_ip_address my_id;
161 
162  int firstrun;
163 
164  qb_loop_timer_handle timer_netif_check_timeout;
165 
166  unsigned int my_memb_entries;
167 
169 
171 
173 
175 
177 
178  qb_loop_timer_handle timer_merge_detect_timeout;
179 
181 
183 };
184 
185 struct work_item {
186  const void *msg;
187  unsigned int msg_len;
189 };
190 
191 static int totemudpu_build_sockets (
192  struct totemudpu_instance *instance,
193  struct totem_ip_address *bindnet_address,
194  struct totem_ip_address *bound_to);
195 
196 static int totemudpu_create_sending_socket(
197  void *udpu_context,
198  const struct totem_ip_address *member);
199 
201  void *udpu_context);
202 
203 static void totemudpu_start_merge_detect_timeout(
204  void *udpu_context);
205 
206 static void totemudpu_stop_merge_detect_timeout(
207  void *udpu_context);
208 
209 static void totemudpu_instance_initialize (struct totemudpu_instance *instance)
210 {
211  memset (instance, 0, sizeof (struct totemudpu_instance));
212 
214 
215  instance->totemudpu_iov_recv.iov_base = instance->iov_buffer;
216 
217  instance->totemudpu_iov_recv.iov_len = UDP_RECEIVE_FRAME_SIZE_MAX; //sizeof (instance->iov_buffer);
218 
219  /*
220  * There is always atleast 1 processor
221  */
222  instance->my_memb_entries = 1;
223 
224  qb_list_init (&instance->member_list);
225 }
226 
227 #define log_printf(level, format, args...) \
228 do { \
229  instance->totemudpu_log_printf ( \
230  level, instance->totemudpu_subsys_id, \
231  __FUNCTION__, __FILE__, __LINE__, \
232  (const char *)format, ##args); \
233 } while (0);
234 #define LOGSYS_PERROR(err_num, level, fmt, args...) \
235 do { \
236  char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
237  const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
238  instance->totemudpu_log_printf ( \
239  level, instance->totemudpu_subsys_id, \
240  __FUNCTION__, __FILE__, __LINE__, \
241  fmt ": %s (%d)", ##args, _error_ptr, err_num); \
242  } while(0)
243 
245  void *udpu_context,
246  const char *cipher_type,
247  const char *hash_type)
248 {
249 
250  return (0);
251 }
252 
253 
254 static inline void ucast_sendmsg (
255  struct totemudpu_instance *instance,
256  struct totem_ip_address *system_to,
257  const void *msg,
258  unsigned int msg_len)
259 {
260  struct msghdr msg_ucast;
261  int res = 0;
262  struct sockaddr_storage sockaddr;
263  struct iovec iovec;
264  int addrlen;
265  int send_sock;
266 
267  iovec.iov_base = (void *)msg;
268  iovec.iov_len = msg_len;
269 
270  /*
271  * Build unicast message
272  */
274  instance->totem_interface->ip_port, &sockaddr, &addrlen);
275  memset(&msg_ucast, 0, sizeof(msg_ucast));
276  msg_ucast.msg_name = &sockaddr;
277  msg_ucast.msg_namelen = addrlen;
278  msg_ucast.msg_iov = (void *)&iovec;
279  msg_ucast.msg_iovlen = 1;
280 #ifdef HAVE_MSGHDR_CONTROL
281  msg_ucast.msg_control = 0;
282 #endif
283 #ifdef HAVE_MSGHDR_CONTROLLEN
284  msg_ucast.msg_controllen = 0;
285 #endif
286 #ifdef HAVE_MSGHDR_FLAGS
287  msg_ucast.msg_flags = 0;
288 #endif
289 #ifdef HAVE_MSGHDR_ACCRIGHTS
290  msg_ucast.msg_accrights = NULL;
291 #endif
292 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
293  msg_ucast.msg_accrightslen = 0;
294 #endif
295 
296  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
297  send_sock = instance->token_socket;
298  } else {
299  send_sock = instance->local_loop_sock[1];
300  msg_ucast.msg_name = NULL;
301  msg_ucast.msg_namelen = 0;
302  }
303 
304 
305  /*
306  * Transmit unicast message
307  * An error here is recovered by totemsrp
308  */
309  res = sendmsg (send_sock, &msg_ucast, MSG_NOSIGNAL);
310  if (res < 0) {
311  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
312  "sendmsg(ucast) failed (non-critical)");
313  }
314 }
315 
316 static inline void mcast_sendmsg (
317  struct totemudpu_instance *instance,
318  const void *msg,
319  unsigned int msg_len,
320  int only_active)
321 {
322  struct msghdr msg_mcast;
323  int res = 0;
324  struct iovec iovec;
325  struct sockaddr_storage sockaddr;
326  int addrlen;
327  struct qb_list_head *list;
328  struct totemudpu_member *member;
329 
330  iovec.iov_base = (void *)msg;
331  iovec.iov_len = msg_len;
332 
333  memset(&msg_mcast, 0, sizeof(msg_mcast));
334  /*
335  * Build multicast message
336  */
337  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
338  qb_list_for_each(list, &(instance->member_list)) {
339  member = qb_list_entry (list,
340  struct totemudpu_member,
341  list);
342  /*
343  * Do not send multicast message if message is not "flush", member
344  * is inactive and timeout for sending merge message didn't expired.
345  */
346  if (only_active && !member->active && !instance->send_merge_detect_message)
347  continue ;
348 
350  instance->totem_interface->ip_port, &sockaddr, &addrlen);
351  msg_mcast.msg_name = &sockaddr;
352  msg_mcast.msg_namelen = addrlen;
353  msg_mcast.msg_iov = (void *)&iovec;
354  msg_mcast.msg_iovlen = 1;
355  #ifdef HAVE_MSGHDR_CONTROL
356  msg_mcast.msg_control = 0;
357  #endif
358  #ifdef HAVE_MSGHDR_CONTROLLEN
359  msg_mcast.msg_controllen = 0;
360  #endif
361  #ifdef HAVE_MSGHDR_FLAGS
362  msg_mcast.msg_flags = 0;
363  #endif
364  #ifdef HAVE_MSGHDR_ACCRIGHTS
365  msg_mcast.msg_accrights = NULL;
366  #endif
367  #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
368  msg_mcast.msg_accrightslen = 0;
369  #endif
370 
371  /*
372  * Transmit multicast message
373  * An error here is recovered by totemsrp
374  */
375  res = sendmsg (member->fd, &msg_mcast, MSG_NOSIGNAL);
376  if (res < 0) {
377  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
378  "sendmsg(mcast) failed (non-critical)");
379  }
380  }
381 
382  if (!only_active || instance->send_merge_detect_message) {
383  /*
384  * Current message was sent to all nodes
385  */
387  instance->send_merge_detect_message = 0;
388  }
389  } else {
390  /*
391  * Transmit multicast message to local unix mcast loop
392  * An error here is recovered by totemsrp
393  */
394  msg_mcast.msg_name = NULL;
395  msg_mcast.msg_namelen = 0;
396  msg_mcast.msg_iov = (void *)&iovec;
397  msg_mcast.msg_iovlen = 1;
398  #ifdef HAVE_MSGHDR_CONTROL
399  msg_mcast.msg_control = 0;
400  #endif
401  #ifdef HAVE_MSGHDR_CONTROLLEN
402  msg_mcast.msg_controllen = 0;
403  #endif
404  #ifdef HAVE_MSGHDR_FLAGS
405  msg_mcast.msg_flags = 0;
406  #endif
407  #ifdef HAVE_MSGHDR_ACCRIGHTS
408  msg_mcast.msg_accrights = NULL;
409  #endif
410  #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
411  msg_mcast.msg_accrightslen = 0;
412  #endif
413 
414  res = sendmsg (instance->local_loop_sock[1], &msg_mcast,
415  MSG_NOSIGNAL);
416  if (res < 0) {
417  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
418  "sendmsg(local mcast loop) failed (non-critical)");
419  }
420  }
421 }
422 
424  void *udpu_context)
425 {
426  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
427  int res = 0;
428 
429  if (instance->token_socket > 0) {
430  qb_loop_poll_del (instance->totemudpu_poll_handle,
431  instance->token_socket);
432  close (instance->token_socket);
433  }
434 
435  if (instance->local_loop_sock[0] > 0) {
436  qb_loop_poll_del (instance->totemudpu_poll_handle,
437  instance->local_loop_sock[0]);
438  close (instance->local_loop_sock[0]);
439  close (instance->local_loop_sock[1]);
440  }
441 
442  totemudpu_stop_merge_detect_timeout(instance);
443 
444  return (res);
445 }
446 
447 static struct totemudpu_member *find_member_by_sockaddr(
448  const void *udpu_context,
449  const struct sockaddr *sa)
450 {
451  struct qb_list_head *list;
452  struct totemudpu_member *member;
453  struct totemudpu_member *res_member;
454  const struct totemudpu_instance *instance = (const struct totemudpu_instance *)udpu_context;
455 
456  res_member = NULL;
457 
458  qb_list_for_each(list, &(instance->member_list)) {
459  member = qb_list_entry (list,
460  struct totemudpu_member,
461  list);
462 
463  if (totemip_sa_equal(&member->member, sa)) {
464  res_member = member;
465  break ;
466  }
467  }
468 
469  return (res_member);
470 }
471 
472 
473 static int net_deliver_fn (
474  int fd,
475  int revents,
476  void *data)
477 {
478  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
479  struct msghdr msg_recv;
480  struct iovec *iovec;
481  struct sockaddr_storage system_from;
482  int bytes_received;
483  int truncated_packet;
484 
485  iovec = &instance->totemudpu_iov_recv;
486 
487  /*
488  * Receive datagram
489  */
490  msg_recv.msg_name = &system_from;
491  msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
492  msg_recv.msg_iov = iovec;
493  msg_recv.msg_iovlen = 1;
494 #ifdef HAVE_MSGHDR_CONTROL
495  msg_recv.msg_control = 0;
496 #endif
497 #ifdef HAVE_MSGHDR_CONTROLLEN
498  msg_recv.msg_controllen = 0;
499 #endif
500 #ifdef HAVE_MSGHDR_FLAGS
501  msg_recv.msg_flags = 0;
502 #endif
503 #ifdef HAVE_MSGHDR_ACCRIGHTS
504  msg_recv.msg_accrights = NULL;
505 #endif
506 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
507  msg_recv.msg_accrightslen = 0;
508 #endif
509 
510  bytes_received = recvmsg (fd, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
511  if (bytes_received == -1) {
512  return (0);
513  } else {
514  instance->stats_recv += bytes_received;
515  }
516 
517  truncated_packet = 0;
518 
519 #ifdef HAVE_MSGHDR_FLAGS
520  if (msg_recv.msg_flags & MSG_TRUNC) {
521  truncated_packet = 1;
522  }
523 #else
524  /*
525  * We don't have MSGHDR_FLAGS, but we can (hopefully) safely make assumption that
526  * if bytes_received == UDP_RECEIVE_FRAME_SIZE_MAX then packet is truncated
527  */
528  if (bytes_received == UDP_RECEIVE_FRAME_SIZE_MAX) {
529  truncated_packet = 1;
530  }
531 #endif
532 
533  if (truncated_packet) {
535  "Received too big message. This may be because something bad is happening"
536  "on the network (attack?), or you tried join more nodes than corosync is"
537  "compiled with (%u) or bug in the code (bad estimation of "
538  "the UDP_RECEIVE_FRAME_SIZE_MAX). Dropping packet.", PROCESSOR_COUNT_MAX);
539  return (0);
540  }
541 
542  if (instance->totem_config->block_unlisted_ips &&
543  find_member_by_sockaddr(instance, (const struct sockaddr *)&system_from) == NULL) {
544  log_printf(instance->totemudpu_log_level_debug, "Packet rejected from %s",
545  totemip_sa_print((const struct sockaddr *)&system_from));
546 
547  return (0);
548  }
549 
550  iovec->iov_len = bytes_received;
551 
552  /*
553  * Handle incoming message
554  */
555  instance->totemudpu_deliver_fn (
556  instance->context,
557  iovec->iov_base,
558  iovec->iov_len,
559  &system_from);
560 
561  iovec->iov_len = UDP_RECEIVE_FRAME_SIZE_MAX;
562  return (0);
563 }
564 
565 static int netif_determine (
566  struct totemudpu_instance *instance,
567  struct totem_ip_address *bindnet,
568  struct totem_ip_address *bound_to,
569  int *interface_up,
570  int *interface_num)
571 {
572  int res;
573 
574  res = totemip_iface_check (bindnet, bound_to,
575  interface_up, interface_num,
576  instance->totem_config->clear_node_high_bit);
577 
578 
579  return (res);
580 }
581 
582 
583 /*
584  * If the interface is up, the sockets for totem are built. If the interface is down
585  * this function is requeued in the timer list to retry building the sockets later.
586  */
587 static void timer_function_netif_check_timeout (
588  void *data)
589 {
590  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
591  int interface_up;
592  int interface_num;
593 
594  /*
595  * Build sockets for every interface
596  */
597  netif_determine (instance,
598  &instance->totem_interface->bindnet,
599  &instance->totem_interface->boundto,
600  &interface_up, &interface_num);
601  /*
602  * If the network interface isn't back up and we are already
603  * in loopback mode, add timer to check again and return
604  */
605  if ((instance->netif_bind_state == BIND_STATE_LOOPBACK &&
606  interface_up == 0) ||
607 
608  (instance->my_memb_entries == 1 &&
609  instance->netif_bind_state == BIND_STATE_REGULAR &&
610  interface_up == 1)) {
611 
612  qb_loop_timer_add (instance->totemudpu_poll_handle,
613  QB_LOOP_MED,
614  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
615  (void *)instance,
616  timer_function_netif_check_timeout,
617  &instance->timer_netif_check_timeout);
618 
619  /*
620  * Add a timer to check for a downed regular interface
621  */
622  return;
623  }
624 
625  if (instance->token_socket > 0) {
626  qb_loop_poll_del (instance->totemudpu_poll_handle,
627  instance->token_socket);
628  close (instance->token_socket);
629  instance->token_socket = -1;
630  }
631 
632  if (interface_up == 0) {
633  if (instance->netif_bind_state == BIND_STATE_UNBOUND) {
635  "One of your ip addresses are now bound to localhost. "
636  "Corosync would not work correctly.");
638  }
639 
640  /*
641  * Interface is not up
642  */
644 
645  /*
646  * Add a timer to retry building interfaces and request memb_gather_enter
647  */
648  qb_loop_timer_add (instance->totemudpu_poll_handle,
649  QB_LOOP_MED,
650  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
651  (void *)instance,
652  timer_function_netif_check_timeout,
653  &instance->timer_netif_check_timeout);
654  } else {
655  /*
656  * Interface is up
657  */
659  }
660  /*
661  * Create and bind the multicast and unicast sockets
662  */
663  totemudpu_build_sockets (instance,
664  &instance->totem_interface->bindnet,
665  &instance->totem_interface->boundto);
666 
667  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
668  qb_loop_poll_add (instance->totemudpu_poll_handle,
669  QB_LOOP_MED,
670  instance->token_socket,
671  POLLIN, instance, net_deliver_fn);
672  }
673 
674  totemip_copy (&instance->my_id, &instance->totem_interface->boundto);
675 
676  /*
677  * This reports changes in the interface to the user and totemsrp
678  */
679  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
680  if (instance->netif_state_report & NETIF_STATE_REPORT_UP) {
682  "The network interface [%s] is now up.",
683  totemip_print (&instance->totem_interface->boundto));
685  instance->totemudpu_iface_change_fn (instance->context, &instance->my_id, 0);
686  }
687  /*
688  * Add a timer to check for interface going down in single membership
689  */
690  if (instance->my_memb_entries == 1) {
691  qb_loop_timer_add (instance->totemudpu_poll_handle,
692  QB_LOOP_MED,
693  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
694  (void *)instance,
695  timer_function_netif_check_timeout,
696  &instance->timer_netif_check_timeout);
697  }
698 
699  } else {
702  "The network interface is down.");
703  instance->totemudpu_iface_change_fn (instance->context, &instance->my_id, 0);
704  }
706 
707  }
708 }
709 
710 /* Set the socket priority to INTERACTIVE to ensure
711  that our messages don't get queued behind anything else */
712 static void totemudpu_traffic_control_set(struct totemudpu_instance *instance, int sock)
713 {
714 #ifdef SO_PRIORITY
715  int prio = 6; /* TC_PRIO_INTERACTIVE */
716 
717  if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int))) {
718  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
719  "Could not set traffic priority");
720  }
721 #endif
722 }
723 
724 static int totemudpu_build_sockets_ip (
725  struct totemudpu_instance *instance,
726  struct totem_ip_address *bindnet_address,
727  struct totem_ip_address *bound_to,
728  int interface_num)
729 {
730  struct sockaddr_storage sockaddr;
731  int addrlen;
732  int res;
733  unsigned int recvbuf_size;
734  unsigned int optlen = sizeof (recvbuf_size);
735  unsigned int retries = 0;
736 
737  /*
738  * Setup unicast socket
739  */
740  instance->token_socket = socket (bindnet_address->family, SOCK_DGRAM, 0);
741  if (instance->token_socket == -1) {
742  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
743  "socket() failed");
744  return (-1);
745  }
746 
747  totemip_nosigpipe (instance->token_socket);
748  res = fcntl (instance->token_socket, F_SETFL, O_NONBLOCK);
749  if (res == -1) {
750  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
751  "Could not set non-blocking operation on token socket");
752  return (-1);
753  }
754 
755  /*
756  * Bind to unicast socket used for token send/receives
757  * This has the side effect of binding to the correct interface
758  */
759  totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
760  while (1) {
761  res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
762  if (res == 0) {
763  break;
764  }
765  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
766  "bind token socket failed");
767  if (++retries > BIND_MAX_RETRIES) {
768  break;
769  }
770 
771  /*
772  * Wait for a while
773  */
774  (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
775  }
776 
777  if (res == -1) {
778  return (-1);
779  }
780 
781  /*
782  * the token_socket can receive many messages. Allow a large number
783  * of receive messages on this socket
784  */
785  recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
786  res = setsockopt (instance->token_socket, SOL_SOCKET, SO_RCVBUF,
787  &recvbuf_size, optlen);
788  if (res == -1) {
789  LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
790  "Could not set recvbuf size");
791  }
792 
793  return 0;
794 }
795 
797  void *net_context,
798  char ***status,
799  unsigned int *iface_count)
800 {
801  static char *statuses[INTERFACE_MAX] = {(char*)"OK"};
802 
803  if (status) {
804  *status = statuses;
805  }
806  *iface_count = 1;
807 
808  return (0);
809 }
810 
811 
812 static int totemudpu_build_local_sockets(
813  struct totemudpu_instance *instance)
814 {
815  int i;
816  unsigned int sendbuf_size;
817  unsigned int recvbuf_size;
818  unsigned int optlen = sizeof (sendbuf_size);
819  int res;
820 
821  /*
822  * Create local multicast loop socket
823  */
824  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, instance->local_loop_sock) == -1) {
825  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
826  "socket() failed");
827  return (-1);
828  }
829 
830  for (i = 0; i < 2; i++) {
831  totemip_nosigpipe (instance->local_loop_sock[i]);
832  res = fcntl (instance->local_loop_sock[i], F_SETFL, O_NONBLOCK);
833  if (res == -1) {
834  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
835  "Could not set non-blocking operation on multicast socket");
836  return (-1);
837  }
838  }
839 
840  recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
841  sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
842 
843  res = setsockopt (instance->local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
844  if (res == -1) {
845  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
846  "Unable to set SO_RCVBUF size on UDP local mcast loop socket");
847  return (-1);
848  }
849  res = setsockopt (instance->local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
850  if (res == -1) {
851  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
852  "Unable to set SO_SNDBUF size on UDP local mcast loop socket");
853  return (-1);
854  }
855 
856  res = getsockopt (instance->local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
857  if (res == 0) {
859  "Local receive multicast loop socket recv buffer size (%d bytes).", recvbuf_size);
860  }
861 
862  res = getsockopt (instance->local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
863  if (res == 0) {
865  "Local transmit multicast loop socket send buffer size (%d bytes).", sendbuf_size);
866  }
867 
868  return (0);
869 }
870 
871 static int totemudpu_build_sockets (
872  struct totemudpu_instance *instance,
873  struct totem_ip_address *bindnet_address,
874  struct totem_ip_address *bound_to)
875 {
876  int interface_num;
877  int interface_up;
878  int res;
879 
880  /*
881  * Determine the ip address bound to and the interface name
882  */
883  res = netif_determine (instance,
884  bindnet_address,
885  bound_to,
886  &interface_up,
887  &interface_num);
888 
889  if (res == -1) {
890  return (-1);
891  }
892 
893  totemip_copy(&instance->my_id, bound_to);
894 
895  res = totemudpu_build_sockets_ip (instance,
896  bindnet_address, bound_to, interface_num);
897 
898  if (res == -1) {
899  /* if we get here, corosync won't work anyway, so better leaving than faking to work */
900  LOGSYS_PERROR (errno, instance->totemudpu_log_level_error,
901  "Unable to create sockets, exiting");
902  exit(EXIT_FAILURE);
903  }
904 
905  /* We only send out of the token socket */
906  totemudpu_traffic_control_set(instance, instance->token_socket);
907 
908  /*
909  * Rebind all members to new ips
910  */
912 
913  return res;
914 }
915 
916 /*
917  * Totem Network interface
918  * depends on poll abstraction, POSIX, IPV4
919  */
920 
921 /*
922  * Create an instance
923  */
925  qb_loop_t *poll_handle,
926  void **udpu_context,
927  struct totem_config *totem_config,
928  totemsrp_stats_t *stats,
929  void *context,
930 
931  void (*deliver_fn) (
932  void *context,
933  const void *msg,
934  unsigned int msg_len,
935  const struct sockaddr_storage *system_from),
936 
937  void (*iface_change_fn) (
938  void *context,
939  const struct totem_ip_address *iface_address,
940  unsigned int ring_no),
941 
942  void (*mtu_changed) (
943  void *context,
944  int net_mtu),
945 
946  void (*target_set_completed) (
947  void *context))
948 {
949  struct totemudpu_instance *instance;
950 
951  instance = malloc (sizeof (struct totemudpu_instance));
952  if (instance == NULL) {
953  return (-1);
954  }
955 
956  totemudpu_instance_initialize (instance);
957 
958  instance->totem_config = totem_config;
959  instance->stats = stats;
960 
961  /*
962  * Configure logging
963  */
964  instance->totemudpu_log_level_security = 1; //totem_config->totem_logging_configuration.log_level_security;
971 
972  /*
973  * Initialize local variables for totemudpu
974  */
975  instance->totem_interface = &totem_config->interfaces[0];
976  memset (instance->iov_buffer, 0, UDP_RECEIVE_FRAME_SIZE_MAX);
977 
978  instance->totemudpu_poll_handle = poll_handle;
979 
980  instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id;
981 
982  instance->context = context;
983  instance->totemudpu_deliver_fn = deliver_fn;
984 
985  instance->totemudpu_iface_change_fn = iface_change_fn;
986 
987  instance->totemudpu_target_set_completed = target_set_completed;
988 
989  /*
990  * Create static local mcast sockets
991  */
992  if (totemudpu_build_local_sockets(instance) == -1) {
993  free(instance);
994  return (-1);
995  }
996 
997  qb_loop_poll_add (
998  instance->totemudpu_poll_handle,
999  QB_LOOP_MED,
1000  instance->local_loop_sock[0],
1001  POLLIN, instance, net_deliver_fn);
1002 
1003  /*
1004  * RRP layer isn't ready to receive message because it hasn't
1005  * initialized yet. Add short timer to check the interfaces.
1006  */
1007  qb_loop_timer_add (instance->totemudpu_poll_handle,
1008  QB_LOOP_MED,
1009  100*QB_TIME_NS_IN_MSEC,
1010  (void *)instance,
1011  timer_function_netif_check_timeout,
1012  &instance->timer_netif_check_timeout);
1013 
1014  totemudpu_start_merge_detect_timeout((void*)instance);
1015 
1016  *udpu_context = instance;
1017  return (0);
1018 }
1019 
1021 {
1022  return malloc (FRAME_SIZE_MAX);
1023 }
1024 
1026 {
1027  return free (ptr);
1028 }
1029 
1031  void *udpu_context,
1032  int processor_count)
1033 {
1034  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1035  int res = 0;
1036 
1037  instance->my_memb_entries = processor_count;
1038  qb_loop_timer_del (instance->totemudpu_poll_handle,
1039  instance->timer_netif_check_timeout);
1040  if (processor_count == 1) {
1041  qb_loop_timer_add (instance->totemudpu_poll_handle,
1042  QB_LOOP_MED,
1043  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
1044  (void *)instance,
1045  timer_function_netif_check_timeout,
1046  &instance->timer_netif_check_timeout);
1047  }
1048 
1049  return (res);
1050 }
1051 
1053 {
1054  int res = 0;
1055 
1056  return (res);
1057 }
1058 
1060 {
1061  int res = 0;
1062 
1063  return (res);
1064 }
1065 
1067  void *udpu_context,
1068  const void *msg,
1069  unsigned int msg_len)
1070 {
1071  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1072  int res = 0;
1073 
1074  ucast_sendmsg (instance, &instance->token_target, msg, msg_len);
1075 
1076  return (res);
1077 }
1079  void *udpu_context,
1080  const void *msg,
1081  unsigned int msg_len)
1082 {
1083  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1084  int res = 0;
1085 
1086  mcast_sendmsg (instance, msg, msg_len, 0);
1087 
1088  return (res);
1089 }
1090 
1092  void *udpu_context,
1093  const void *msg,
1094  unsigned int msg_len)
1095 {
1096  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1097  int res = 0;
1098 
1099  mcast_sendmsg (instance, msg, msg_len, 1);
1100 
1101  return (res);
1102 }
1103 
1105 {
1106  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1107  int res = 0;
1108 
1109  timer_function_netif_check_timeout (instance);
1110 
1111  return (res);
1112 }
1113 
1115 {
1117 }
1118 
1119 
1121  void *udpu_context,
1122  unsigned int nodeid)
1123 {
1124 
1125  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1126  struct qb_list_head *list;
1127  struct totemudpu_member *member;
1128  int res = 0;
1129 
1130  qb_list_for_each(list, &(instance->member_list)) {
1131  member = qb_list_entry (list,
1132  struct totemudpu_member,
1133  list);
1134 
1135  if (member->member.nodeid == nodeid) {
1136  memcpy (&instance->token_target, &member->member,
1137  sizeof (struct totem_ip_address));
1138 
1139  instance->totemudpu_target_set_completed (instance->context);
1140  break;
1141  }
1142  }
1143  return (res);
1144 }
1145 
1147  void *udpu_context)
1148 {
1149  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1150  unsigned int res;
1151  struct sockaddr_storage system_from;
1152  struct msghdr msg_recv;
1153  struct pollfd ufd;
1154  int nfds, i;
1155  int msg_processed = 0;
1156  int sock;
1157 
1158  /*
1159  * Receive datagram
1160  */
1161  msg_recv.msg_name = &system_from;
1162  msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
1163  msg_recv.msg_iov = &instance->totemudpu_iov_recv;
1164  msg_recv.msg_iovlen = 1;
1165 #ifdef HAVE_MSGHDR_CONTROL
1166  msg_recv.msg_control = 0;
1167 #endif
1168 #ifdef HAVE_MSGHDR_CONTROLLEN
1169  msg_recv.msg_controllen = 0;
1170 #endif
1171 #ifdef HAVE_MSGHDR_FLAGS
1172  msg_recv.msg_flags = 0;
1173 #endif
1174 #ifdef HAVE_MSGHDR_ACCRIGHTS
1175  msg_recv.msg_accrights = NULL;
1176 #endif
1177 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
1178  msg_recv.msg_accrightslen = 0;
1179 #endif
1180 
1181  for (i = 0; i < 2; i++) {
1182  sock = -1;
1183  if (i == 0) {
1184  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
1185  sock = instance->token_socket;
1186  } else {
1187  continue;
1188  }
1189  }
1190  if (i == 1) {
1191  sock = instance->local_loop_sock[0];
1192  }
1193  assert(sock != -1);
1194 
1195  do {
1196  ufd.fd = sock;
1197  ufd.events = POLLIN;
1198  nfds = poll (&ufd, 1, 0);
1199  if (nfds == 1 && ufd.revents & POLLIN) {
1200  res = recvmsg (sock, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
1201  if (res != -1) {
1202  msg_processed = 1;
1203  } else {
1204  msg_processed = -1;
1205  }
1206  }
1207  } while (nfds == 1);
1208  }
1209 
1210  return (msg_processed);
1211 }
1212 
1213 static int totemudpu_create_sending_socket(
1214  void *udpu_context,
1215  const struct totem_ip_address *member)
1216 {
1217  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1218  int fd;
1219  int res;
1220  unsigned int sendbuf_size;
1221  unsigned int optlen = sizeof (sendbuf_size);
1222  struct sockaddr_storage sockaddr;
1223  int addrlen;
1224 
1225  fd = socket (member->family, SOCK_DGRAM, 0);
1226  if (fd == -1) {
1227  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1228  "Could not create socket for new member");
1229  return (-1);
1230  }
1231  totemip_nosigpipe (fd);
1232  res = fcntl (fd, F_SETFL, O_NONBLOCK);
1233  if (res == -1) {
1234  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1235  "Could not set non-blocking operation on token socket");
1236  goto error_close_fd;
1237  }
1238 
1239  /*
1240  * These sockets are used to send multicast messages, so their buffers
1241  * should be large
1242  */
1243  sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
1244  res = setsockopt (fd, SOL_SOCKET, SO_SNDBUF,
1245  &sendbuf_size, optlen);
1246  if (res == -1) {
1247  LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
1248  "Could not set sendbuf size");
1249  /*
1250  * Fail in setting sendbuf size is not fatal -> don't exit
1251  */
1252  }
1253 
1254  /*
1255  * Bind to sending interface
1256  */
1257  totemip_totemip_to_sockaddr_convert(&instance->my_id, 0, &sockaddr, &addrlen);
1258  res = bind (fd, (struct sockaddr *)&sockaddr, addrlen);
1259  if (res == -1) {
1260  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1261  "bind token socket failed");
1262  goto error_close_fd;
1263  }
1264 
1265  return (fd);
1266 
1267 error_close_fd:
1268  close(fd);
1269  return (-1);
1270 }
1271 
1272 int totemudpu_iface_set (void *net_context,
1273  const struct totem_ip_address *local_addr,
1274  unsigned short ip_port,
1275  unsigned int iface_no)
1276 {
1277  /* Not supported */
1278  return (-1);
1279 }
1280 
1282  void *udpu_context,
1283  const struct totem_ip_address *local,
1284  const struct totem_ip_address *member,
1285  int ring_no)
1286 {
1287  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1288 
1289  struct totemudpu_member *new_member;
1290 
1291  new_member = malloc (sizeof (struct totemudpu_member));
1292  if (new_member == NULL) {
1293  return (-1);
1294  }
1295 
1296  memset(new_member, 0, sizeof(*new_member));
1297 
1298  log_printf (LOGSYS_LEVEL_NOTICE, "adding new UDPU member {%s}",
1300  qb_list_init (&new_member->list);
1301  qb_list_add_tail (&new_member->list, &instance->member_list);
1302  memcpy (&new_member->member, member, sizeof (struct totem_ip_address));
1303  new_member->fd = totemudpu_create_sending_socket(udpu_context, member);
1304  new_member->active = 1;
1305 
1306  return (0);
1307 }
1308 
1310  void *udpu_context,
1311  const struct totem_ip_address *token_target,
1312  int ring_no)
1313 {
1314  int found = 0;
1315  struct qb_list_head *list;
1316  struct totemudpu_member *member;
1317 
1318  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1319 
1320  /*
1321  * Find the member to remove and close its socket
1322  */
1323  qb_list_for_each(list, &(instance->member_list)) {
1324  member = qb_list_entry (list,
1325  struct totemudpu_member,
1326  list);
1327 
1328  if (totemip_compare (token_target, &member->member)==0) {
1330  "removing UDPU member {%s}",
1331  totemip_print(&member->member));
1332 
1333  if (member->fd > 0) {
1335  "Closing socket to: {%s}",
1336  totemip_print(&member->member));
1337  qb_loop_poll_del (instance->totemudpu_poll_handle,
1338  member->fd);
1339  close (member->fd);
1340  }
1341  found = 1;
1342  break;
1343  }
1344  }
1345 
1346  /*
1347  * Delete the member from the list
1348  */
1349  if (found) {
1350  qb_list_del (list);
1351  }
1352 
1353  instance = NULL;
1354  return (0);
1355 }
1356 
1358  void *udpu_context)
1359 {
1360  struct qb_list_head *list;
1361  struct totemudpu_member *member;
1362 
1363  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1364 
1365  qb_list_for_each(list, &(instance->member_list)) {
1366  member = qb_list_entry (list,
1367  struct totemudpu_member,
1368  list);
1369 
1370  if (member->fd > 0) {
1371  close (member->fd);
1372  }
1373 
1374  member->fd = totemudpu_create_sending_socket(udpu_context, &member->member);
1375  }
1376 
1377  return (0);
1378 }
1379 
1380 
1381 static void timer_function_merge_detect_timeout (
1382  void *data)
1383 {
1384  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
1385 
1386  if (instance->merge_detect_messages_sent_before_timeout == 0) {
1387  instance->send_merge_detect_message = 1;
1388  }
1389 
1391 
1392  totemudpu_start_merge_detect_timeout(instance);
1393 }
1394 
1395 static void totemudpu_start_merge_detect_timeout(
1396  void *udpu_context)
1397 {
1398  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1399 
1400  qb_loop_timer_add(instance->totemudpu_poll_handle,
1401  QB_LOOP_MED,
1402  instance->totem_config->merge_timeout * 2 * QB_TIME_NS_IN_MSEC,
1403  (void *)instance,
1404  timer_function_merge_detect_timeout,
1405  &instance->timer_merge_detect_timeout);
1406 
1407 }
1408 
1409 static void totemudpu_stop_merge_detect_timeout(
1410  void *udpu_context)
1411 {
1412  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1413 
1414  qb_loop_timer_del(instance->totemudpu_poll_handle,
1415  instance->timer_merge_detect_timeout);
1416 }
1417 
1419  void *udpu_context,
1420  struct totem_config *totem_config)
1421 {
1422  /* Not supported */
1423  return (-1);
1424 }
totemudpu_instance::iov_buffer
char iov_buffer[UDP_RECEIVE_FRAME_SIZE_MAX]
Definition: totemudpu.c:142
work_item::instance
struct totemudpu_instance * instance
Definition: totemudpu.c:188
totemudpu_processor_count_set
int totemudpu_processor_count_set(void *udpu_context, int processor_count)
Definition: totemudpu.c:1030
UDP_RECEIVE_FRAME_SIZE_MAX
#define UDP_RECEIVE_FRAME_SIZE_MAX
Definition: totem.h:62
totemudpu_instance::totemudpu_deliver_fn
void(* totemudpu_deliver_fn)(void *context, const void *msg, unsigned int msg_len, const struct sockaddr_storage *system_from)
Definition: totemudpu.c:103
totem_logging_configuration::log_level_error
int log_level_error
Definition: totem.h:111
totemudpu_buffer_alloc
void * totemudpu_buffer_alloc(void)
Definition: totemudpu.c:1020
BIND_RETRIES_INTERVAL
#define BIND_RETRIES_INTERVAL
Definition: totem.h:71
totemudpu_instance::totemudpu_log_level_security
int totemudpu_log_level_security
Definition: totemudpu.c:119
totem_config::node_id
unsigned int node_id
Definition: totem.h:167
totemudpu_member::member
struct totem_ip_address member
Definition: totemudpu.c:87
totemudpu_instance::stats_orf_token
int stats_orf_token
Definition: totemudpu.c:156
totemudpu_recv_mcast_empty
int totemudpu_recv_mcast_empty(void *udpu_context)
Definition: totemudpu.c:1146
MCAST_SOCKET_BUFFER_SIZE
#define MCAST_SOCKET_BUFFER_SIZE
Definition: totemudpu.c:77
totemudpu_instance::totem_config
struct totem_config * totem_config
Definition: totemudpu.c:168
totem_config::downcheck_timeout
unsigned int downcheck_timeout
Definition: totem.h:199
work_item::msg_len
unsigned int msg_len
Definition: totemknet.c:191
totemudpu_net_mtu_adjust
void totemudpu_net_mtu_adjust(void *udpu_context, struct totem_config *totem_config)
Definition: totemudpu.c:1114
MSG_NOSIGNAL
#define MSG_NOSIGNAL
Definition: totemudpu.c:74
totemudpu.h
totemudpu_instance::stats
totemsrp_stats_t * stats
Definition: totemudpu.c:170
totemudpu_finalize
int totemudpu_finalize(void *udpu_context)
Definition: totemudpu.c:423
totemudpu_mcast_flush_send
int totemudpu_mcast_flush_send(void *udpu_context, const void *msg, unsigned int msg_len)
Definition: totemudpu.c:1078
totemudpu_instance::totemudpu_iface_change_fn
void(* totemudpu_iface_change_fn)(void *context, const struct totem_ip_address *iface_address, unsigned int ring_no)
Definition: totemudpu.c:109
totemudpu_instance::totemudpu_log_level_debug
int totemudpu_log_level_debug
Definition: totemudpu.c:127
totemudpu_instance::member_list
struct qb_list_head member_list
Definition: totemudpu.c:146
work_item
Definition: totemknet.c:189
totemudpu_instance::my_memb_entries
unsigned int my_memb_entries
Definition: totemudpu.c:166
LOGSYS_LEVEL_DEBUG
#define LOGSYS_LEVEL_DEBUG
Definition: logsys.h:76
totem_logging_configuration::log_level_debug
int log_level_debug
Definition: totem.h:114
totemip_print
const char * totemip_print(const struct totem_ip_address *addr)
Definition: totemip.c:256
totemsrp_stats_t
Definition: totemstats.h:53
totem_logging_configuration::log_level_notice
int log_level_notice
Definition: totem.h:113
totemudpu_member_list_rebind_ip
int totemudpu_member_list_rebind_ip(void *udpu_context)
Definition: totemudpu.c:1357
totemip_compare
int totemip_compare(const void *a, const void *b)
Definition: totemip.c:150
totemudpu_mcast_noflush_send
int totemudpu_mcast_noflush_send(void *udpu_context, const void *msg, unsigned int msg_len)
Definition: totemudpu.c:1091
totemudpu_instance::totemudpu_log_printf
void(* totemudpu_log_printf)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf
Definition: totemudpu.c:131
BIND_STATE_UNBOUND
#define BIND_STATE_UNBOUND
Definition: totemudpu.c:81
totemudpu_initialize
int totemudpu_initialize(qb_loop_t *poll_handle, void **udpu_context, struct totem_config *totem_config, totemsrp_stats_t *stats, void *context, void(*deliver_fn)(void *context, const void *msg, unsigned int msg_len, const struct sockaddr_storage *system_from), void(*iface_change_fn)(void *context, const struct totem_ip_address *iface_address, unsigned int ring_no), void(*mtu_changed)(void *context, int net_mtu), void(*target_set_completed)(void *context))
Create an instance.
Definition: totemudpu.c:924
totemudpu_instance::timer_merge_detect_timeout
qb_loop_timer_handle timer_merge_detect_timeout
Definition: totemudpu.c:178
totemudpu_instance::stats_remcasts
int stats_remcasts
Definition: totemudpu.c:154
totemudpu_instance::netif_bind_state
int netif_bind_state
Definition: totemudpu.c:99
totem_ip_address::nodeid
unsigned int nodeid
Definition: coroapi.h:112
totemudpu_instance::firstrun
int firstrun
Definition: totemudpu.c:162
totem_config::merge_timeout
unsigned int merge_timeout
Definition: totem.h:197
totem_interface
Definition: totem.h:82
FRAME_SIZE_MAX
#define FRAME_SIZE_MAX
Definition: totem.h:52
totemudpu_instance::totemudpu_log_level_warning
int totemudpu_log_level_warning
Definition: totemudpu.c:123
swab.h
totemip_sa_equal
int totemip_sa_equal(const struct totem_ip_address *totem_ip, const struct sockaddr *sa)
Definition: totemip.c:95
totem_config::interfaces
struct totem_interface * interfaces
Definition: totem.h:165
totemip_copy
void totemip_copy(struct totem_ip_address *addr1, const struct totem_ip_address *addr2)
Definition: totemip.c:123
totemip_nosigpipe
#define totemip_nosigpipe(s)
Definition: totemip.h:56
totemudpu_instance::udpu_context
void(*) void udpu_context)
Definition: totemudpu.c:138
totemudpu_instance::totemudpu_subsys_id
int totemudpu_subsys_id
Definition: totemudpu.c:129
totemip_iface_check
int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num, int mask_high_bit)
Definition: totemip.c:529
totemudpu_instance::merge_detect_messages_sent_before_timeout
unsigned int merge_detect_messages_sent_before_timeout
Definition: totemudpu.c:182
totemudpu_instance
Definition: totemudpu.c:92
totemudpu_iface_set
int totemudpu_iface_set(void *net_context, const struct totem_ip_address *local_addr, unsigned short ip_port, unsigned int iface_no)
Definition: totemudpu.c:1272
BIND_STATE_LOOPBACK
#define BIND_STATE_LOOPBACK
Definition: totemudpu.c:83
totemudpu_instance::totemudpu_poll_handle
qb_loop_t * totemudpu_poll_handle
Definition: totemudpu.c:93
__attribute__
typedef __attribute__
NETIF_STATE_REPORT_DOWN
#define NETIF_STATE_REPORT_DOWN
Definition: totemudpu.c:79
totem_config::net_mtu
unsigned int net_mtu
Definition: totem.h:209
totem_config::clear_node_high_bit
unsigned int clear_node_high_bit
Definition: totem.h:168
totemudpu_member
Definition: totemudpu.c:85
totemudpu_instance::token_socket
int token_socket
Definition: totemudpu.c:174
INTERFACE_MAX
#define INTERFACE_MAX
Definition: coroapi.h:88
totemudpu_instance::stats_sent
int stats_sent
Definition: totemudpu.c:148
totemudpu_reconfigure
int totemudpu_reconfigure(void *udpu_context, struct totem_config *totem_config)
Definition: totemudpu.c:1418
totemudpu_instance::send_merge_detect_message
int send_merge_detect_message
Definition: totemudpu.c:180
totemudpu_buffer_release
void totemudpu_buffer_release(void *ptr)
Definition: totemudpu.c:1025
totemudpu_instance::timer_netif_check_timeout
qb_loop_timer_handle timer_netif_check_timeout
Definition: totemudpu.c:164
totemudpu_member_remove
int totemudpu_member_remove(void *udpu_context, const struct totem_ip_address *token_target, int ring_no)
Definition: totemudpu.c:1309
totem_interface::boundto
struct totem_ip_address boundto
Definition: totem.h:84
totemudpu_instance::netif_state_report
int netif_state_report
Definition: totemudpu.c:97
totemudpu_token_send
int totemudpu_token_send(void *udpu_context, const void *msg, unsigned int msg_len)
Definition: totemudpu.c:1066
totemip_udpip_header_size
size_t totemip_udpip_header_size(int family)
Definition: totemip.c:608
totemudpu_token_target_set
int totemudpu_token_target_set(void *udpu_context, unsigned int nodeid)
Definition: totemudpu.c:1120
totem_logging_configuration::log_subsys_id
int log_subsys_id
Definition: totem.h:116
totem_ip_address::family
unsigned short family
Definition: coroapi.h:113
totemudpu_instance::totemudpu_target_set_completed
void(* totemudpu_target_set_completed)(void *context)
Definition: totemudpu.c:114
totemudpu_instance::totemudpu_iov_recv
struct iovec totemudpu_iov_recv
Definition: totemudpu.c:144
totem_config
Definition: totem.h:159
LOGSYS_LEVEL_NOTICE
#define LOGSYS_LEVEL_NOTICE
Definition: logsys.h:74
totemudpu_member::fd
int fd
Definition: totemudpu.c:88
NETIF_STATE_REPORT_UP
#define NETIF_STATE_REPORT_UP
Definition: totemudpu.c:78
totemudpu_member::active
int active
Definition: totemudpu.c:89
totem_ip_address
The totem_ip_address struct.
Definition: coroapi.h:111
totemudpu_instance::totem_interface
struct totem_interface * totem_interface
Definition: totemudpu.c:95
sq.h
totemip_sa_print
const char * totemip_sa_print(const struct sockaddr *sa)
Definition: totemip.c:234
totemudpu_instance::stats_tv_start
struct timeval stats_tv_start
Definition: totemudpu.c:158
totemudpu_instance::context
void * context
Definition: totemudpu.c:101
BIND_STATE_REGULAR
#define BIND_STATE_REGULAR
Definition: totemudpu.c:82
totemudpu_instance::stats_delv
int stats_delv
Definition: totemudpu.c:152
totem_interface::ip_port
uint16_t ip_port
Definition: totem.h:87
totemudpu_instance::local_loop_sock
int local_loop_sock[2]
Definition: totemudpu.c:176
totemudpu_instance::token_target
struct totem_ip_address token_target
Definition: totemudpu.c:172
work_item::msg
const void * msg
Definition: totemknet.c:190
system_from
struct srp_addr system_from
Definition: totemsrp.c:1
totem_logging_configuration::log_level_warning
int log_level_warning
Definition: totem.h:112
totemudpu_send_flush
int totemudpu_send_flush(void *udpu_context)
Definition: totemudpu.c:1059
util.h
totemudpu_recv_flush
int totemudpu_recv_flush(void *udpu_context)
Definition: totemudpu.c:1052
totemudpu_member::list
struct qb_list_head list
Definition: totemudpu.c:86
totemudpu_ifaces_get
int totemudpu_ifaces_get(void *net_context, char ***status, unsigned int *iface_count)
Definition: totemudpu.c:796
LOGSYS_PERROR
#define LOGSYS_PERROR(err_num, level, fmt, args...)
Definition: totemudpu.c:234
BIND_MAX_RETRIES
#define BIND_MAX_RETRIES
Definition: totem.h:70
nodeid
unsigned int nodeid
Definition: coroapi.h:0
totemudpu_instance::totemudpu_log_level_notice
int totemudpu_log_level_notice
Definition: totemudpu.c:125
log_printf
#define log_printf(level, format, args...)
Definition: totemudpu.c:227
totemudpu_instance::totemudpu_log_level_error
int totemudpu_log_level_error
Definition: totemudpu.c:121
PROCESSOR_COUNT_MAX
#define PROCESSOR_COUNT_MAX
Definition: coroapi.h:96
config.h
totemudpu_member_add
int totemudpu_member_add(void *udpu_context, const struct totem_ip_address *local, const struct totem_ip_address *member, int ring_no)
Definition: totemudpu.c:1281
logsys.h
totem_logging_configuration::log_printf
void(* log_printf)(int level, int subsys, const char *function_name, const char *file_name, int file_line, const char *format,...) __attribute__((format(printf
Definition: totem.h:101
totem_interface::bindnet
struct totem_ip_address bindnet
Definition: totem.h:83
totemip_totemip_to_sockaddr_convert
int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
Definition: totemip.c:264
totem_config::block_unlisted_ips
unsigned int block_unlisted_ips
Definition: totem.h:245
totemudpu_crypto_set
int totemudpu_crypto_set(void *udpu_context, const char *cipher_type, const char *hash_type)
Definition: totemudpu.c:244
totemudpu_iface_check
int totemudpu_iface_check(void *udpu_context)
Definition: totemudpu.c:1104
COROSYNC_DONE_FATAL_ERR
@ COROSYNC_DONE_FATAL_ERR
Definition: exec/util.h:55
totemudpu_instance::my_id
struct totem_ip_address my_id
Definition: totemudpu.c:160
totemudpu_instance::stats_recv
int stats_recv
Definition: totemudpu.c:150
totem_config::totem_logging_configuration
struct totem_logging_configuration totem_logging_configuration
Definition: totem.h:207