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