corosync  2.4.4
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 
182  qb_loop_timer_handle timer_merge_detect_timeout;
183 
185 
187 };
188 
189 struct work_item {
190  const void *msg;
191  unsigned int msg_len;
193 };
194 
195 static int totemudpu_build_sockets (
196  struct totemudpu_instance *instance,
197  struct totem_ip_address *bindnet_address,
198  struct totem_ip_address *bound_to);
199 
200 static int totemudpu_create_sending_socket(
201  void *udpu_context,
202  const struct totem_ip_address *member);
203 
205  void *udpu_context);
206 
207 static void totemudpu_start_merge_detect_timeout(
208  void *udpu_context);
209 
210 static void totemudpu_stop_merge_detect_timeout(
211  void *udpu_context);
212 
213 static struct totem_ip_address localhost;
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 
274  if (msg_len + crypto_get_current_sec_header_size(instance->crypto_inst) > sizeof(buf_out)) {
275  log_printf(LOGSYS_LEVEL_CRIT, "UDPU message for ucast is too big. Ignoring message");
276 
277  return ;
278  }
279 
280  /*
281  * Encrypt and digest the message
282  */
284  instance->crypto_inst,
285  (const unsigned char *)msg,
286  msg_len,
287  buf_out,
288  &buf_out_len) != 0) {
289  log_printf(LOGSYS_LEVEL_CRIT, "Error encrypting/signing packet (non-critical)");
290  return;
291  }
292 
293  iovec.iov_base = (void *)buf_out;
294  iovec.iov_len = buf_out_len;
295 
296  /*
297  * Build unicast message
298  */
300  instance->totem_interface->ip_port, &sockaddr, &addrlen);
301  memset(&msg_ucast, 0, sizeof(msg_ucast));
302  msg_ucast.msg_name = &sockaddr;
303  msg_ucast.msg_namelen = addrlen;
304  msg_ucast.msg_iov = (void *)&iovec;
305  msg_ucast.msg_iovlen = 1;
306 #ifdef HAVE_MSGHDR_CONTROL
307  msg_ucast.msg_control = 0;
308 #endif
309 #ifdef HAVE_MSGHDR_CONTROLLEN
310  msg_ucast.msg_controllen = 0;
311 #endif
312 #ifdef HAVE_MSGHDR_FLAGS
313  msg_ucast.msg_flags = 0;
314 #endif
315 #ifdef HAVE_MSGHDR_ACCRIGHTS
316  msg_ucast.msg_accrights = NULL;
317 #endif
318 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
319  msg_ucast.msg_accrightslen = 0;
320 #endif
321 
322 
323  /*
324  * Transmit unicast message
325  * An error here is recovered by totemsrp
326  */
327  res = sendmsg (instance->token_socket, &msg_ucast, MSG_NOSIGNAL);
328  if (res < 0) {
329  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
330  "sendmsg(ucast) failed (non-critical)");
331  }
332 }
333 
334 static inline void mcast_sendmsg (
335  struct totemudpu_instance *instance,
336  const void *msg,
337  unsigned int msg_len,
338  int only_active)
339 {
340  struct msghdr msg_mcast;
341  int res = 0;
342  size_t buf_out_len;
343  unsigned char buf_out[FRAME_SIZE_MAX];
344  struct iovec iovec;
345  struct sockaddr_storage sockaddr;
346  int addrlen;
347  struct list_head *list;
348  struct totemudpu_member *member;
349 
350  if (msg_len + crypto_get_current_sec_header_size(instance->crypto_inst) > sizeof(buf_out)) {
351  log_printf(LOGSYS_LEVEL_CRIT, "UDPU message for mcast is too big. Ignoring message");
352 
353  return ;
354  }
355 
356  /*
357  * Encrypt and digest the message
358  */
360  instance->crypto_inst,
361  (const unsigned char *)msg,
362  msg_len,
363  buf_out,
364  &buf_out_len) != 0) {
365  log_printf(LOGSYS_LEVEL_CRIT, "Error encrypting/signing packet (non-critical)");
366  return;
367  }
368 
369  iovec.iov_base = (void *)buf_out;
370  iovec.iov_len = buf_out_len;
371 
372  memset(&msg_mcast, 0, sizeof(msg_mcast));
373  /*
374  * Build multicast message
375  */
376  for (list = instance->member_list.next;
377  list != &instance->member_list;
378  list = list->next) {
379 
380  member = list_entry (list,
381  struct totemudpu_member,
382  list);
383 
384  /*
385  * Do not send multicast message if message is not "flush", member
386  * is inactive and timeout for sending merge message didn't expired.
387  */
388  if (only_active && !member->active && !instance->send_merge_detect_message)
389  continue ;
390 
392  instance->totem_interface->ip_port, &sockaddr, &addrlen);
393  msg_mcast.msg_name = &sockaddr;
394  msg_mcast.msg_namelen = addrlen;
395  msg_mcast.msg_iov = (void *)&iovec;
396  msg_mcast.msg_iovlen = 1;
397  #ifdef HAVE_MSGHDR_CONTROL
398  msg_mcast.msg_control = 0;
399  #endif
400  #ifdef HAVE_MSGHDR_CONTROLLEN
401  msg_mcast.msg_controllen = 0;
402  #endif
403  #ifdef HAVE_MSGHDR_FLAGS
404  msg_mcast.msg_flags = 0;
405  #endif
406  #ifdef HAVE_MSGHDR_ACCRIGHTS
407  msg_mcast.msg_accrights = NULL;
408  #endif
409  #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
410  msg_mcast.msg_accrightslen = 0;
411  #endif
412 
413  /*
414  * Transmit multicast message
415  * An error here is recovered by totemsrp
416  */
417  res = sendmsg (member->fd, &msg_mcast, MSG_NOSIGNAL);
418  if (res < 0) {
419  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
420  "sendmsg(mcast) failed (non-critical)");
421  }
422  }
423 
424  if (!only_active || instance->send_merge_detect_message) {
425  /*
426  * Current message was sent to all nodes
427  */
429  instance->send_merge_detect_message = 0;
430  }
431 }
432 
434  void *udpu_context)
435 {
436  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
437  int res = 0;
438 
439  if (instance->token_socket > 0) {
440  qb_loop_poll_del (instance->totemudpu_poll_handle,
441  instance->token_socket);
442  close (instance->token_socket);
443  }
444 
445  totemudpu_stop_merge_detect_timeout(instance);
446 
447  return (res);
448 }
449 
450 static int net_deliver_fn (
451  int fd,
452  int revents,
453  void *data)
454 {
455  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
456  struct msghdr msg_recv;
457  struct iovec *iovec;
458  struct sockaddr_storage system_from;
459  int bytes_received;
460  int res = 0;
461  int truncated_packet;
462 
463  iovec = &instance->totemudpu_iov_recv;
464 
465  /*
466  * Receive datagram
467  */
468  msg_recv.msg_name = &system_from;
469  msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
470  msg_recv.msg_iov = iovec;
471  msg_recv.msg_iovlen = 1;
472 #ifdef HAVE_MSGHDR_CONTROL
473  msg_recv.msg_control = 0;
474 #endif
475 #ifdef HAVE_MSGHDR_CONTROLLEN
476  msg_recv.msg_controllen = 0;
477 #endif
478 #ifdef HAVE_MSGHDR_FLAGS
479  msg_recv.msg_flags = 0;
480 #endif
481 #ifdef HAVE_MSGHDR_ACCRIGHTS
482  msg_recv.msg_accrights = NULL;
483 #endif
484 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
485  msg_recv.msg_accrightslen = 0;
486 #endif
487 
488  bytes_received = recvmsg (fd, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
489  if (bytes_received == -1) {
490  return (0);
491  } else {
492  instance->stats_recv += bytes_received;
493  }
494 
495  truncated_packet = 0;
496 
497 #ifdef HAVE_MSGHDR_FLAGS
498  if (msg_recv.msg_flags & MSG_TRUNC) {
499  truncated_packet = 1;
500  }
501 #else
502  /*
503  * We don't have MSGHDR_FLAGS, but we can (hopefully) safely make assumption that
504  * if bytes_received == FRAME_SIZE_MAX then packet is truncated
505  */
506  if (bytes_received == FRAME_SIZE_MAX) {
507  truncated_packet = 1;
508  }
509 #endif
510 
511  if (truncated_packet) {
513  "Received too big message. This may be because something bad is happening"
514  "on the network (attack?), or you tried join more nodes than corosync is"
515  "compiled with (%u) or bug in the code (bad estimation of "
516  "the FRAME_SIZE_MAX). Dropping packet.", PROCESSOR_COUNT_MAX);
517  return (0);
518  }
519 
520  /*
521  * Authenticate and if authenticated, decrypt datagram
522  */
523 
524  res = crypto_authenticate_and_decrypt (instance->crypto_inst, iovec->iov_base, &bytes_received);
525  if (res == -1) {
526  log_printf (instance->totemudpu_log_level_security, "Received message has invalid digest... ignoring.");
528  "Invalid packet data");
529  iovec->iov_len = FRAME_SIZE_MAX;
530  return 0;
531  }
532  iovec->iov_len = bytes_received;
533 
534  /*
535  * Handle incoming message
536  */
537  instance->totemudpu_deliver_fn (
538  instance->context,
539  iovec->iov_base,
540  iovec->iov_len);
541 
542  iovec->iov_len = FRAME_SIZE_MAX;
543  return (0);
544 }
545 
546 static int netif_determine (
547  struct totemudpu_instance *instance,
548  struct totem_ip_address *bindnet,
549  struct totem_ip_address *bound_to,
550  int *interface_up,
551  int *interface_num)
552 {
553  int res;
554 
555  res = totemip_iface_check (bindnet, bound_to,
556  interface_up, interface_num,
557  instance->totem_config->clear_node_high_bit);
558 
559 
560  return (res);
561 }
562 
563 
564 /*
565  * If the interface is up, the sockets for totem are built. If the interface is down
566  * this function is requeued in the timer list to retry building the sockets later.
567  */
568 static void timer_function_netif_check_timeout (
569  void *data)
570 {
571  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
572  int interface_up;
573  int interface_num;
574  struct totem_ip_address *bind_address;
575 
576  /*
577  * Build sockets for every interface
578  */
579  netif_determine (instance,
580  &instance->totem_interface->bindnet,
581  &instance->totem_interface->boundto,
582  &interface_up, &interface_num);
583  /*
584  * If the network interface isn't back up and we are already
585  * in loopback mode, add timer to check again and return
586  */
587  if ((instance->netif_bind_state == BIND_STATE_LOOPBACK &&
588  interface_up == 0) ||
589 
590  (instance->my_memb_entries == 1 &&
591  instance->netif_bind_state == BIND_STATE_REGULAR &&
592  interface_up == 1)) {
593 
594  qb_loop_timer_add (instance->totemudpu_poll_handle,
595  QB_LOOP_MED,
596  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
597  (void *)instance,
598  timer_function_netif_check_timeout,
599  &instance->timer_netif_check_timeout);
600 
601  /*
602  * Add a timer to check for a downed regular interface
603  */
604  return;
605  }
606 
607  if (instance->token_socket > 0) {
608  qb_loop_poll_del (instance->totemudpu_poll_handle,
609  instance->token_socket);
610  close (instance->token_socket);
611  }
612 
613  if (interface_up == 0) {
614  /*
615  * Interface is not up
616  */
618  bind_address = &localhost;
619 
620  /*
621  * Add a timer to retry building interfaces and request memb_gather_enter
622  */
623  qb_loop_timer_add (instance->totemudpu_poll_handle,
624  QB_LOOP_MED,
625  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
626  (void *)instance,
627  timer_function_netif_check_timeout,
628  &instance->timer_netif_check_timeout);
629  } else {
630  /*
631  * Interface is up
632  */
634  bind_address = &instance->totem_interface->bindnet;
635  }
636  /*
637  * Create and bind the multicast and unicast sockets
638  */
639  totemudpu_build_sockets (instance,
640  bind_address,
641  &instance->totem_interface->boundto);
642 
643  qb_loop_poll_add (instance->totemudpu_poll_handle,
644  QB_LOOP_MED,
645  instance->token_socket,
646  POLLIN, instance, net_deliver_fn);
647 
648  totemip_copy (&instance->my_id, &instance->totem_interface->boundto);
649 
650  /*
651  * This reports changes in the interface to the user and totemsrp
652  */
653  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
654  if (instance->netif_state_report & NETIF_STATE_REPORT_UP) {
656  "The network interface [%s] is now up.",
657  totemip_print (&instance->totem_interface->boundto));
659  instance->totemudpu_iface_change_fn (instance->context, &instance->my_id);
660  }
661  /*
662  * Add a timer to check for interface going down in single membership
663  */
664  if (instance->my_memb_entries == 1) {
665  qb_loop_timer_add (instance->totemudpu_poll_handle,
666  QB_LOOP_MED,
667  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
668  (void *)instance,
669  timer_function_netif_check_timeout,
670  &instance->timer_netif_check_timeout);
671  }
672 
673  } else {
676  "The network interface is down.");
677  instance->totemudpu_iface_change_fn (instance->context, &instance->my_id);
678  }
680 
681  }
682 }
683 
684 /* Set the socket priority to INTERACTIVE to ensure
685  that our messages don't get queued behind anything else */
686 static void totemudpu_traffic_control_set(struct totemudpu_instance *instance, int sock)
687 {
688 #ifdef SO_PRIORITY
689  int prio = 6; /* TC_PRIO_INTERACTIVE */
690 
691  if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int))) {
692  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
693  "Could not set traffic priority");
694  }
695 #endif
696 }
697 
698 static int totemudpu_build_sockets_ip (
699  struct totemudpu_instance *instance,
700  struct totem_ip_address *bindnet_address,
701  struct totem_ip_address *bound_to,
702  int interface_num)
703 {
704  struct sockaddr_storage sockaddr;
705  int addrlen;
706  int res;
707  unsigned int recvbuf_size;
708  unsigned int optlen = sizeof (recvbuf_size);
709  unsigned int retries = 0;
710 
711  /*
712  * Setup unicast socket
713  */
714  instance->token_socket = socket (bindnet_address->family, SOCK_DGRAM, 0);
715  if (instance->token_socket == -1) {
716  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
717  "socket() failed");
718  return (-1);
719  }
720 
721  totemip_nosigpipe (instance->token_socket);
722  res = fcntl (instance->token_socket, F_SETFL, O_NONBLOCK);
723  if (res == -1) {
724  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
725  "Could not set non-blocking operation on token socket");
726  return (-1);
727  }
728 
729  /*
730  * Bind to unicast socket used for token send/receives
731  * This has the side effect of binding to the correct interface
732  */
733  totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
734  while (1) {
735  res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
736  if (res == 0) {
737  break;
738  }
739  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
740  "bind token socket failed");
741  if (++retries > BIND_MAX_RETRIES) {
742  break;
743  }
744 
745  /*
746  * Wait for a while
747  */
748  (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
749  }
750 
751  if (res == -1) {
752  return (-1);
753  }
754 
755  /*
756  * the token_socket can receive many messages. Allow a large number
757  * of receive messages on this socket
758  */
759  recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
760  res = setsockopt (instance->token_socket, SOL_SOCKET, SO_RCVBUF,
761  &recvbuf_size, optlen);
762  if (res == -1) {
763  LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
764  "Could not set recvbuf size");
765  }
766 
767  return 0;
768 }
769 
770 static int totemudpu_build_sockets (
771  struct totemudpu_instance *instance,
772  struct totem_ip_address *bindnet_address,
773  struct totem_ip_address *bound_to)
774 {
775  int interface_num;
776  int interface_up;
777  int res;
778 
779  /*
780  * Determine the ip address bound to and the interface name
781  */
782  res = netif_determine (instance,
783  bindnet_address,
784  bound_to,
785  &interface_up,
786  &interface_num);
787 
788  if (res == -1) {
789  return (-1);
790  }
791 
792  totemip_copy(&instance->my_id, bound_to);
793 
794  res = totemudpu_build_sockets_ip (instance,
795  bindnet_address, bound_to, interface_num);
796 
797  if (res == -1) {
798  /* if we get here, corosync won't work anyway, so better leaving than faking to work */
799  LOGSYS_PERROR (errno, instance->totemudpu_log_level_error,
800  "Unable to create sockets, exiting");
801  exit(EXIT_FAILURE);
802  }
803 
804  /* We only send out of the token socket */
805  totemudpu_traffic_control_set(instance, instance->token_socket);
806 
807  /*
808  * Rebind all members to new ips
809  */
811 
812  return res;
813 }
814 
815 /*
816  * Totem Network interface - also does encryption/decryption
817  * depends on poll abstraction, POSIX, IPV4
818  */
819 
820 /*
821  * Create an instance
822  */
824  qb_loop_t *poll_handle,
825  void **udpu_context,
826  struct totem_config *totem_config,
827  totemsrp_stats_t *stats,
828  int interface_no,
829  void *context,
830 
831  void (*deliver_fn) (
832  void *context,
833  const void *msg,
834  unsigned int msg_len),
835 
836  void (*iface_change_fn) (
837  void *context,
838  const struct totem_ip_address *iface_address),
839 
840  void (*target_set_completed) (
841  void *context))
842 {
843  struct totemudpu_instance *instance;
844 
845  instance = malloc (sizeof (struct totemudpu_instance));
846  if (instance == NULL) {
847  return (-1);
848  }
849 
850  totemudpu_instance_initialize (instance);
851 
852  instance->totem_config = totem_config;
853  instance->stats = stats;
854 
855  /*
856  * Configure logging
857  */
858  instance->totemudpu_log_level_security = 1; //totem_config->totem_logging_configuration.log_level_security;
865 
866  /*
867  * Initialize random number generator for later use to generate salt
868  */
869  instance->crypto_inst = crypto_init (totem_config->private_key,
870  totem_config->private_key_len,
871  totem_config->crypto_cipher_type,
872  totem_config->crypto_hash_type,
873  instance->totemudpu_log_printf,
875  instance->totemudpu_log_level_notice,
876  instance->totemudpu_log_level_error,
877  instance->totemudpu_subsys_id);
878  if (instance->crypto_inst == NULL) {
879  free(instance);
880  return (-1);
881  }
882  /*
883  * Initialize local variables for totemudpu
884  */
885  instance->totem_interface = &totem_config->interfaces[interface_no];
886  memset (instance->iov_buffer, 0, FRAME_SIZE_MAX);
887 
888  instance->totemudpu_poll_handle = poll_handle;
889 
890  instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id;
891 
892  instance->context = context;
893  instance->totemudpu_deliver_fn = deliver_fn;
894 
895  instance->totemudpu_iface_change_fn = iface_change_fn;
896 
897  instance->totemudpu_target_set_completed = target_set_completed;
898 
899  totemip_localhost (AF_INET, &localhost);
900  localhost.nodeid = instance->totem_config->node_id;
901 
902  /*
903  * RRP layer isn't ready to receive message because it hasn't
904  * initialized yet. Add short timer to check the interfaces.
905  */
906  qb_loop_timer_add (instance->totemudpu_poll_handle,
907  QB_LOOP_MED,
908  100*QB_TIME_NS_IN_MSEC,
909  (void *)instance,
910  timer_function_netif_check_timeout,
911  &instance->timer_netif_check_timeout);
912 
913  totemudpu_start_merge_detect_timeout(instance);
914 
915  *udpu_context = instance;
916  return (0);
917 }
918 
920 {
921  return malloc (FRAME_SIZE_MAX);
922 }
923 
924 void totemudpu_buffer_release (void *ptr)
925 {
926  return free (ptr);
927 }
928 
930  void *udpu_context,
931  int processor_count)
932 {
933  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
934  int res = 0;
935 
936  instance->my_memb_entries = processor_count;
937  qb_loop_timer_del (instance->totemudpu_poll_handle,
938  instance->timer_netif_check_timeout);
939  if (processor_count == 1) {
940  qb_loop_timer_add (instance->totemudpu_poll_handle,
941  QB_LOOP_MED,
942  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
943  (void *)instance,
944  timer_function_netif_check_timeout,
945  &instance->timer_netif_check_timeout);
946  }
947 
948  return (res);
949 }
950 
951 int totemudpu_recv_flush (void *udpu_context)
952 {
953  int res = 0;
954 
955  return (res);
956 }
957 
958 int totemudpu_send_flush (void *udpu_context)
959 {
960  int res = 0;
961 
962  return (res);
963 }
964 
966  void *udpu_context,
967  const void *msg,
968  unsigned int msg_len)
969 {
970  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
971  int res = 0;
972 
973  ucast_sendmsg (instance, &instance->token_target, msg, msg_len);
974 
975  return (res);
976 }
978  void *udpu_context,
979  const void *msg,
980  unsigned int msg_len)
981 {
982  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
983  int res = 0;
984 
985  mcast_sendmsg (instance, msg, msg_len, 0);
986 
987  return (res);
988 }
989 
991  void *udpu_context,
992  const void *msg,
993  unsigned int msg_len)
994 {
995  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
996  int res = 0;
997 
998  mcast_sendmsg (instance, msg, msg_len, 1);
999 
1000  return (res);
1001 }
1002 
1003 extern int totemudpu_iface_check (void *udpu_context)
1004 {
1005  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1006  int res = 0;
1007 
1008  timer_function_netif_check_timeout (instance);
1009 
1010  return (res);
1011 }
1012 
1013 extern void totemudpu_net_mtu_adjust (void *udpu_context, struct totem_config *totem_config)
1014 {
1015 
1016  assert(totem_config->interface_count > 0);
1017 
1018  totem_config->net_mtu -= crypto_sec_header_size(totem_config->crypto_cipher_type,
1019  totem_config->crypto_hash_type) +
1021 }
1022 
1023 const char *totemudpu_iface_print (void *udpu_context) {
1024  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1025  const char *ret_char;
1026 
1027  ret_char = totemip_print (&instance->my_id);
1028 
1029  return (ret_char);
1030 }
1031 
1033  void *udpu_context,
1034  struct totem_ip_address *addr)
1035 {
1036  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1037  int res = 0;
1038 
1039  memcpy (addr, &instance->my_id, sizeof (struct totem_ip_address));
1040 
1041  return (res);
1042 }
1043 
1045  void *udpu_context,
1046  const struct totem_ip_address *token_target)
1047 {
1048  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1049  int res = 0;
1050 
1051  memcpy (&instance->token_target, token_target,
1052  sizeof (struct totem_ip_address));
1053 
1054  instance->totemudpu_target_set_completed (instance->context);
1055 
1056  return (res);
1057 }
1058 
1060  void *udpu_context)
1061 {
1062  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1063  unsigned int res;
1064  struct sockaddr_storage system_from;
1065  struct msghdr msg_recv;
1066  struct pollfd ufd;
1067  int nfds;
1068  int msg_processed = 0;
1069 
1070  /*
1071  * Receive datagram
1072  */
1073  msg_recv.msg_name = &system_from;
1074  msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
1075  msg_recv.msg_iov = &instance->totemudpu_iov_recv;
1076  msg_recv.msg_iovlen = 1;
1077 #ifdef HAVE_MSGHDR_CONTROL
1078  msg_recv.msg_control = 0;
1079 #endif
1080 #ifdef HAVE_MSGHDR_CONTROLLEN
1081  msg_recv.msg_controllen = 0;
1082 #endif
1083 #ifdef HAVE_MSGHDR_FLAGS
1084  msg_recv.msg_flags = 0;
1085 #endif
1086 #ifdef HAVE_MSGHDR_ACCRIGHTS
1087  msg_recv.msg_accrights = NULL;
1088 #endif
1089 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
1090  msg_recv.msg_accrightslen = 0;
1091 #endif
1092 
1093  do {
1094  ufd.fd = instance->token_socket;
1095  ufd.events = POLLIN;
1096  nfds = poll (&ufd, 1, 0);
1097  if (nfds == 1 && ufd.revents & POLLIN) {
1098  res = recvmsg (instance->token_socket, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
1099  if (res != -1) {
1100  msg_processed = 1;
1101  } else {
1102  msg_processed = -1;
1103  }
1104  }
1105  } while (nfds == 1);
1106 
1107  return (msg_processed);
1108 }
1109 
1110 static int totemudpu_create_sending_socket(
1111  void *udpu_context,
1112  const struct totem_ip_address *member)
1113 {
1114  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1115  int fd;
1116  int res;
1117  unsigned int sendbuf_size;
1118  unsigned int optlen = sizeof (sendbuf_size);
1119  struct sockaddr_storage sockaddr;
1120  int addrlen;
1121 
1122  fd = socket (member->family, SOCK_DGRAM, 0);
1123  if (fd == -1) {
1124  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1125  "Could not create socket for new member");
1126  return (-1);
1127  }
1128  totemip_nosigpipe (fd);
1129  res = fcntl (fd, F_SETFL, O_NONBLOCK);
1130  if (res == -1) {
1131  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1132  "Could not set non-blocking operation on token socket");
1133  goto error_close_fd;
1134  }
1135 
1136  /*
1137  * These sockets are used to send multicast messages, so their buffers
1138  * should be large
1139  */
1140  sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
1141  res = setsockopt (fd, SOL_SOCKET, SO_SNDBUF,
1142  &sendbuf_size, optlen);
1143  if (res == -1) {
1144  LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
1145  "Could not set sendbuf size");
1146  /*
1147  * Fail in setting sendbuf size is not fatal -> don't exit
1148  */
1149  }
1150 
1151  /*
1152  * Bind to sending interface
1153  */
1154  totemip_totemip_to_sockaddr_convert(&instance->my_id, 0, &sockaddr, &addrlen);
1155  res = bind (fd, (struct sockaddr *)&sockaddr, addrlen);
1156  if (res == -1) {
1157  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1158  "bind token socket failed");
1159  goto error_close_fd;
1160  }
1161 
1162  return (fd);
1163 
1164 error_close_fd:
1165  close(fd);
1166  return (-1);
1167 }
1168 
1170  void *udpu_context,
1171  const struct totem_ip_address *member)
1172 {
1173  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1174 
1175  struct totemudpu_member *new_member;
1176 
1177  new_member = malloc (sizeof (struct totemudpu_member));
1178  if (new_member == NULL) {
1179  return (-1);
1180  }
1181 
1182  memset(new_member, 0, sizeof(*new_member));
1183 
1184  log_printf (LOGSYS_LEVEL_NOTICE, "adding new UDPU member {%s}",
1185  totemip_print(member));
1186  list_init (&new_member->list);
1187  list_add_tail (&new_member->list, &instance->member_list);
1188  memcpy (&new_member->member, member, sizeof (struct totem_ip_address));
1189  new_member->fd = totemudpu_create_sending_socket(udpu_context, member);
1190  new_member->active = 0;
1191 
1192  return (0);
1193 }
1194 
1196  void *udpu_context,
1197  const struct totem_ip_address *token_target)
1198 {
1199  int found = 0;
1200  struct list_head *list;
1201  struct totemudpu_member *member;
1202 
1203  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1204 
1205  /*
1206  * Find the member to remove and close its socket
1207  */
1208  for (list = instance->member_list.next;
1209  list != &instance->member_list;
1210  list = list->next) {
1211 
1212  member = list_entry (list,
1213  struct totemudpu_member,
1214  list);
1215 
1216  if (totemip_compare (token_target, &member->member)==0) {
1218  "removing UDPU member {%s}",
1219  totemip_print(&member->member));
1220 
1221  if (member->fd > 0) {
1223  "Closing socket to: {%s}",
1224  totemip_print(&member->member));
1225  qb_loop_poll_del (instance->totemudpu_poll_handle,
1226  member->fd);
1227  close (member->fd);
1228  }
1229  found = 1;
1230  break;
1231  }
1232  }
1233 
1234  /*
1235  * Delete the member from the list
1236  */
1237  if (found) {
1238  list_del (list);
1239  }
1240 
1241  instance = NULL;
1242  return (0);
1243 }
1244 
1246  void *udpu_context)
1247 {
1248  struct list_head *list;
1249  struct totemudpu_member *member;
1250 
1251  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1252 
1253  for (list = instance->member_list.next;
1254  list != &instance->member_list;
1255  list = list->next) {
1256 
1257  member = list_entry (list,
1258  struct totemudpu_member,
1259  list);
1260 
1261  if (member->fd > 0) {
1262  close (member->fd);
1263  }
1264 
1265  member->fd = totemudpu_create_sending_socket(udpu_context, &member->member);
1266  }
1267 
1268  return (0);
1269 }
1270 
1272  void *udpu_context,
1273  const struct totem_ip_address *member_ip,
1274  int active)
1275 {
1276  struct list_head *list;
1277  struct totemudpu_member *member;
1278  int addr_found = 0;
1279 
1280  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1281 
1282  /*
1283  * Find the member to set active flag
1284  */
1285  for (list = instance->member_list.next; list != &instance->member_list; list = list->next) {
1286  member = list_entry (list, struct totemudpu_member, list);
1287 
1288  if (totemip_compare (member_ip, &member->member) == 0) {
1290  "Marking UDPU member %s %s",
1291  totemip_print(&member->member),
1292  (active ? "active" : "inactive"));
1293 
1294  member->active = active;
1295  addr_found = 1;
1296 
1297  break;
1298  }
1299  }
1300 
1301  if (!addr_found) {
1303  "Can't find UDPU member %s (should be marked as %s)",
1304  totemip_print(member_ip),
1305  (active ? "active" : "inactive"));
1306  }
1307 
1308  return (0);
1309 }
1310 
1311 static void timer_function_merge_detect_timeout (
1312  void *data)
1313 {
1314  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
1315 
1316  if (instance->merge_detect_messages_sent_before_timeout == 0) {
1317  instance->send_merge_detect_message = 1;
1318  }
1319 
1321 
1322  totemudpu_start_merge_detect_timeout(instance);
1323 }
1324 
1325 static void totemudpu_start_merge_detect_timeout(
1326  void *udpu_context)
1327 {
1328  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1329 
1330  qb_loop_timer_add(instance->totemudpu_poll_handle,
1331  QB_LOOP_MED,
1332  instance->totem_config->merge_timeout * 2 * QB_TIME_NS_IN_MSEC,
1333  (void *)instance,
1334  timer_function_merge_detect_timeout,
1335  &instance->timer_merge_detect_timeout);
1336 
1337 }
1338 
1339 static void totemudpu_stop_merge_detect_timeout(
1340  void *udpu_context)
1341 {
1342  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1343 
1344  qb_loop_timer_del(instance->totemudpu_poll_handle,
1345  instance->timer_merge_detect_timeout);
1346 }
unsigned int clear_node_high_bit
Definition: totem.h:120
unsigned short family
Definition: coroapi.h:113
#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
int totemip_localhost(int family, struct totem_ip_address *localhost)
Definition: totemip.c:182
void(* totemudpu_iface_change_fn)(void *context, const struct totem_ip_address *iface_address)
Definition: totemudpu.c:116
unsigned int my_memb_entries
Definition: totemudpu.c:172
#define BIND_MAX_RETRIES
Definition: totem.h:55
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:776
The totem_ip_address struct.
Definition: coroapi.h:111
int totemudpu_token_target_set(void *udpu_context, const struct totem_ip_address *token_target)
Definition: totemudpu.c:1044
const char * totemip_print(const struct totem_ip_address *addr)
Definition: totemip.c:214
struct totem_ip_address my_id
Definition: totemudpu.c:166
size_t crypto_get_current_sec_header_size(const struct crypto_instance *instance)
Definition: totemcrypto.c:811
struct totemudpu_instance * instance
Definition: totemudpu.c:192
#define NETIF_STATE_REPORT_DOWN
Definition: totemudpu.c:85
int totemip_compare(const void *a, const void *b)
Definition: totemip.c:130
#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:929
unsigned char addr[TOTEMIP_ADDRLEN]
Definition: coroapi.h:77
int totemudpu_log_level_security
Definition: totemudpu.c:125
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:930
void totemip_copy(struct totem_ip_address *addr1, const struct totem_ip_address *addr2)
Definition: totemip.c:95
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:182
Definition: list.h:46
int send_merge_detect_message
Definition: totemudpu.c:184
#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:1023
struct iovec totemudpu_iov_recv
Definition: totemudpu.c:150
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:405
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:832
void(*) void udpu_context)
Definition: totemudpu.c:144
void totemudpu_buffer_release(void *ptr)
Definition: totemudpu.c:924
void * totemudpu_buffer_alloc(void)
Definition: totemudpu.c:919
unsigned int merge_detect_messages_sent_before_timeout
Definition: totemudpu.c:186
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:990
unsigned int nodeid
Definition: coroapi.h:112
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
char * crypto_hash_type
Definition: totem.h:186
totemsrp_stats_t * stats
Definition: totemudpu.c:176
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
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
#define LOGSYS_LEVEL_DEBUG
Definition: logsys.h:74
void(* totemudpu_target_set_completed)(void *context)
Definition: totemudpu.c:120
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:965
struct totem_ip_address boundto
Definition: totem.h:69
typedef __attribute__
size_t totemip_udpip_header_size(int family)
Definition: totemip.c:496
struct list_head member_list
Definition: totemudpu.c:152
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
#define BIND_STATE_LOOPBACK
Definition: totemudpu.c:89
unsigned int net_mtu
Definition: totem.h:168
#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:854
int totemudpu_member_remove(void *udpu_context, const struct totem_ip_address *token_target)
Definition: totemudpu.c:1195
int totemudpu_member_set_active(void *udpu_context, const struct totem_ip_address *member_ip, int active)
Definition: totemudpu.c:1271
void(* totemudpu_deliver_fn)(void *context, const void *msg, unsigned int msg_len)
Definition: totemudpu.c:111
#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:222
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:1059
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:823
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:1013
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:977
int totemudpu_send_flush(void *udpu_context)
Definition: totemudpu.c:958
int totemudpu_finalize(void *udpu_context)
Definition: totemudpu.c:433
struct crypto_instance * crypto_inst
Definition: totemudpu.c:99
int totemudpu_recv_flush(void *udpu_context)
Definition: totemudpu.c:951
unsigned int msg_len
Definition: totemudp.c:197
int totemudpu_member_add(void *udpu_context, const struct totem_ip_address *member)
Definition: totemudpu.c:1169
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:1032
int totemudpu_member_list_rebind_ip(void *udpu_context)
Definition: totemudpu.c:1245
int totemudpu_iface_check(void *udpu_context)
Definition: totemudpu.c:1003
int totemudpu_log_level_notice
Definition: totemudpu.c:131