corosync  2.4.5
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  find_member_by_sockaddr(instance, (const struct sockaddr *)&system_from) == NULL) {
601  log_printf(instance->totemudpu_log_level_debug, "Packet rejected from %s",
602  totemip_sa_print((const struct sockaddr *)&system_from));
603 
604  return (0);
605  }
606 
607  /*
608  * Authenticate and if authenticated, decrypt datagram
609  */
610 
611  res = crypto_authenticate_and_decrypt (instance->crypto_inst, iovec->iov_base, &bytes_received);
612  if (res == -1) {
613  log_printf (instance->totemudpu_log_level_security, "Received message has invalid digest... ignoring.");
615  "Invalid packet data");
616  iovec->iov_len = FRAME_SIZE_MAX;
617  return 0;
618  }
619  iovec->iov_len = bytes_received;
620 
621  /*
622  * Handle incoming message
623  */
624  instance->totemudpu_deliver_fn (
625  instance->context,
626  iovec->iov_base,
627  iovec->iov_len);
628 
629  iovec->iov_len = FRAME_SIZE_MAX;
630  return (0);
631 }
632 
633 static int netif_determine (
634  struct totemudpu_instance *instance,
635  struct totem_ip_address *bindnet,
636  struct totem_ip_address *bound_to,
637  int *interface_up,
638  int *interface_num)
639 {
640  int res;
641 
642  res = totemip_iface_check (bindnet, bound_to,
643  interface_up, interface_num,
644  instance->totem_config->clear_node_high_bit);
645 
646 
647  return (res);
648 }
649 
650 
651 /*
652  * If the interface is up, the sockets for totem are built. If the interface is down
653  * this function is requeued in the timer list to retry building the sockets later.
654  */
655 static void timer_function_netif_check_timeout (
656  void *data)
657 {
658  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
659  int interface_up;
660  int interface_num;
661 
662  /*
663  * Build sockets for every interface
664  */
665  netif_determine (instance,
666  &instance->totem_interface->bindnet,
667  &instance->totem_interface->boundto,
668  &interface_up, &interface_num);
669  /*
670  * If the network interface isn't back up and we are already
671  * in loopback mode, add timer to check again and return
672  */
673  if ((instance->netif_bind_state == BIND_STATE_LOOPBACK &&
674  interface_up == 0) ||
675 
676  (instance->my_memb_entries == 1 &&
677  instance->netif_bind_state == BIND_STATE_REGULAR &&
678  interface_up == 1)) {
679 
680  qb_loop_timer_add (instance->totemudpu_poll_handle,
681  QB_LOOP_MED,
682  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
683  (void *)instance,
684  timer_function_netif_check_timeout,
685  &instance->timer_netif_check_timeout);
686 
687  /*
688  * Add a timer to check for a downed regular interface
689  */
690  return;
691  }
692 
693  if (instance->token_socket > 0) {
694  qb_loop_poll_del (instance->totemudpu_poll_handle,
695  instance->token_socket);
696  close (instance->token_socket);
697  instance->token_socket = -1;
698  }
699 
700  if (interface_up == 0) {
701  if (instance->netif_bind_state == BIND_STATE_UNBOUND) {
703  "One of your ip addresses are now bound to localhost. "
704  "Corosync would not work correctly.");
706  }
707 
708  /*
709  * Interface is not up
710  */
712 
713  /*
714  * Add a timer to retry building interfaces and request memb_gather_enter
715  */
716  qb_loop_timer_add (instance->totemudpu_poll_handle,
717  QB_LOOP_MED,
718  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
719  (void *)instance,
720  timer_function_netif_check_timeout,
721  &instance->timer_netif_check_timeout);
722  } else {
723  /*
724  * Interface is up
725  */
727  }
728  /*
729  * Create and bind the multicast and unicast sockets
730  */
731  totemudpu_build_sockets (instance,
732  &instance->totem_interface->bindnet,
733  &instance->totem_interface->boundto);
734 
735  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
736  qb_loop_poll_add (instance->totemudpu_poll_handle,
737  QB_LOOP_MED,
738  instance->token_socket,
739  POLLIN, instance, net_deliver_fn);
740  }
741 
742  totemip_copy (&instance->my_id, &instance->totem_interface->boundto);
743 
744  /*
745  * This reports changes in the interface to the user and totemsrp
746  */
747  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
748  if (instance->netif_state_report & NETIF_STATE_REPORT_UP) {
750  "The network interface [%s] is now up.",
751  totemip_print (&instance->totem_interface->boundto));
753  instance->totemudpu_iface_change_fn (instance->context, &instance->my_id);
754  }
755  /*
756  * Add a timer to check for interface going down in single membership
757  */
758  if (instance->my_memb_entries == 1) {
759  qb_loop_timer_add (instance->totemudpu_poll_handle,
760  QB_LOOP_MED,
761  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
762  (void *)instance,
763  timer_function_netif_check_timeout,
764  &instance->timer_netif_check_timeout);
765  }
766 
767  } else {
770  "The network interface is down.");
771  instance->totemudpu_iface_change_fn (instance->context, &instance->my_id);
772  }
774 
775  }
776 }
777 
778 /* Set the socket priority to INTERACTIVE to ensure
779  that our messages don't get queued behind anything else */
780 static void totemudpu_traffic_control_set(struct totemudpu_instance *instance, int sock)
781 {
782 #ifdef SO_PRIORITY
783  int prio = 6; /* TC_PRIO_INTERACTIVE */
784 
785  if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int))) {
786  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
787  "Could not set traffic priority");
788  }
789 #endif
790 }
791 
792 static int totemudpu_build_sockets_ip (
793  struct totemudpu_instance *instance,
794  struct totem_ip_address *bindnet_address,
795  struct totem_ip_address *bound_to,
796  int interface_num)
797 {
798  struct sockaddr_storage sockaddr;
799  int addrlen;
800  int res;
801  unsigned int recvbuf_size;
802  unsigned int optlen = sizeof (recvbuf_size);
803  unsigned int retries = 0;
804 
805  /*
806  * Setup unicast socket
807  */
808  instance->token_socket = socket (bindnet_address->family, SOCK_DGRAM, 0);
809  if (instance->token_socket == -1) {
810  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
811  "socket() failed");
812  return (-1);
813  }
814 
815  totemip_nosigpipe (instance->token_socket);
816  res = fcntl (instance->token_socket, F_SETFL, O_NONBLOCK);
817  if (res == -1) {
818  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
819  "Could not set non-blocking operation on token socket");
820  return (-1);
821  }
822 
823  /*
824  * Bind to unicast socket used for token send/receives
825  * This has the side effect of binding to the correct interface
826  */
827  totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
828  while (1) {
829  res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
830  if (res == 0) {
831  break;
832  }
833  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
834  "bind token socket failed");
835  if (++retries > BIND_MAX_RETRIES) {
836  break;
837  }
838 
839  /*
840  * Wait for a while
841  */
842  (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
843  }
844 
845  if (res == -1) {
846  return (-1);
847  }
848 
849  /*
850  * the token_socket can receive many messages. Allow a large number
851  * of receive messages on this socket
852  */
853  recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
854  res = setsockopt (instance->token_socket, SOL_SOCKET, SO_RCVBUF,
855  &recvbuf_size, optlen);
856  if (res == -1) {
857  LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
858  "Could not set recvbuf size");
859  }
860 
861  return 0;
862 }
863 
864 static int totemudpu_build_local_sockets(
865  struct totemudpu_instance *instance)
866 {
867  int i;
868  unsigned int sendbuf_size;
869  unsigned int recvbuf_size;
870  unsigned int optlen = sizeof (sendbuf_size);
871  int res;
872 
873  /*
874  * Create local multicast loop socket
875  */
876  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, instance->local_loop_sock) == -1) {
877  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
878  "socket() failed");
879  return (-1);
880  }
881 
882  for (i = 0; i < 2; i++) {
883  totemip_nosigpipe (instance->local_loop_sock[i]);
884  res = fcntl (instance->local_loop_sock[i], F_SETFL, O_NONBLOCK);
885  if (res == -1) {
886  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
887  "Could not set non-blocking operation on multicast socket");
888  return (-1);
889  }
890  }
891 
892  recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
893  sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
894 
895  res = setsockopt (instance->local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
896  if (res == -1) {
897  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
898  "Unable to set SO_RCVBUF size on UDP local mcast loop socket");
899  return (-1);
900  }
901  res = setsockopt (instance->local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
902  if (res == -1) {
903  LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
904  "Unable to set SO_SNDBUF size on UDP local mcast loop socket");
905  return (-1);
906  }
907 
908  res = getsockopt (instance->local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
909  if (res == 0) {
911  "Local receive multicast loop socket recv buffer size (%d bytes).", recvbuf_size);
912  }
913 
914  res = getsockopt (instance->local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
915  if (res == 0) {
917  "Local transmit multicast loop socket send buffer size (%d bytes).", sendbuf_size);
918  }
919 
920  return (0);
921 }
922 
923 static int totemudpu_build_sockets (
924  struct totemudpu_instance *instance,
925  struct totem_ip_address *bindnet_address,
926  struct totem_ip_address *bound_to)
927 {
928  int interface_num;
929  int interface_up;
930  int res;
931 
932  /*
933  * Determine the ip address bound to and the interface name
934  */
935  res = netif_determine (instance,
936  bindnet_address,
937  bound_to,
938  &interface_up,
939  &interface_num);
940 
941  if (res == -1) {
942  return (-1);
943  }
944 
945  totemip_copy(&instance->my_id, bound_to);
946 
947  res = totemudpu_build_sockets_ip (instance,
948  bindnet_address, bound_to, interface_num);
949 
950  if (res == -1) {
951  /* if we get here, corosync won't work anyway, so better leaving than faking to work */
952  LOGSYS_PERROR (errno, instance->totemudpu_log_level_error,
953  "Unable to create sockets, exiting");
954  exit(EXIT_FAILURE);
955  }
956 
957  /* We only send out of the token socket */
958  totemudpu_traffic_control_set(instance, instance->token_socket);
959 
960  /*
961  * Rebind all members to new ips
962  */
964 
965  return res;
966 }
967 
968 /*
969  * Totem Network interface - also does encryption/decryption
970  * depends on poll abstraction, POSIX, IPV4
971  */
972 
973 /*
974  * Create an instance
975  */
977  qb_loop_t *poll_handle,
978  void **udpu_context,
979  struct totem_config *totem_config,
980  totemsrp_stats_t *stats,
981  int interface_no,
982  void *context,
983 
984  void (*deliver_fn) (
985  void *context,
986  const void *msg,
987  unsigned int msg_len),
988 
989  void (*iface_change_fn) (
990  void *context,
991  const struct totem_ip_address *iface_address),
992 
993  void (*target_set_completed) (
994  void *context))
995 {
996  struct totemudpu_instance *instance;
997 
998  instance = malloc (sizeof (struct totemudpu_instance));
999  if (instance == NULL) {
1000  return (-1);
1001  }
1002 
1003  totemudpu_instance_initialize (instance);
1004 
1005  instance->totem_config = totem_config;
1006  instance->stats = stats;
1007 
1008  /*
1009  * Configure logging
1010  */
1011  instance->totemudpu_log_level_security = 1; //totem_config->totem_logging_configuration.log_level_security;
1018 
1019  /*
1020  * Initialize random number generator for later use to generate salt
1021  */
1022  instance->crypto_inst = crypto_init (totem_config->private_key,
1023  totem_config->private_key_len,
1024  totem_config->crypto_cipher_type,
1025  totem_config->crypto_hash_type,
1026  instance->totemudpu_log_printf,
1027  instance->totemudpu_log_level_security,
1028  instance->totemudpu_log_level_notice,
1029  instance->totemudpu_log_level_error,
1030  instance->totemudpu_subsys_id);
1031  if (instance->crypto_inst == NULL) {
1032  free(instance);
1033  return (-1);
1034  }
1035  /*
1036  * Initialize local variables for totemudpu
1037  */
1038  instance->totem_interface = &totem_config->interfaces[interface_no];
1039  memset (instance->iov_buffer, 0, FRAME_SIZE_MAX);
1040 
1041  instance->totemudpu_poll_handle = poll_handle;
1042 
1043  instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id;
1044 
1045  instance->context = context;
1046  instance->totemudpu_deliver_fn = deliver_fn;
1047 
1048  instance->totemudpu_iface_change_fn = iface_change_fn;
1049 
1050  instance->totemudpu_target_set_completed = target_set_completed;
1051 
1052  /*
1053  * Create static local mcast sockets
1054  */
1055  if (totemudpu_build_local_sockets(instance) == -1) {
1056  free(instance);
1057  return (-1);
1058  }
1059 
1060  qb_loop_poll_add (
1061  instance->totemudpu_poll_handle,
1062  QB_LOOP_MED,
1063  instance->local_loop_sock[0],
1064  POLLIN, instance, net_deliver_fn);
1065 
1066  /*
1067  * RRP layer isn't ready to receive message because it hasn't
1068  * initialized yet. Add short timer to check the interfaces.
1069  */
1070  qb_loop_timer_add (instance->totemudpu_poll_handle,
1071  QB_LOOP_MED,
1072  100*QB_TIME_NS_IN_MSEC,
1073  (void *)instance,
1074  timer_function_netif_check_timeout,
1075  &instance->timer_netif_check_timeout);
1076 
1077  totemudpu_start_merge_detect_timeout((void*)instance);
1078 
1079  *udpu_context = instance;
1080  return (0);
1081 }
1082 
1084 {
1085  return malloc (FRAME_SIZE_MAX);
1086 }
1087 
1089 {
1090  return free (ptr);
1091 }
1092 
1094  void *udpu_context,
1095  int processor_count)
1096 {
1097  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1098  int res = 0;
1099 
1100  instance->my_memb_entries = processor_count;
1101  qb_loop_timer_del (instance->totemudpu_poll_handle,
1102  instance->timer_netif_check_timeout);
1103  if (processor_count == 1) {
1104  qb_loop_timer_add (instance->totemudpu_poll_handle,
1105  QB_LOOP_MED,
1106  instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
1107  (void *)instance,
1108  timer_function_netif_check_timeout,
1109  &instance->timer_netif_check_timeout);
1110  }
1111 
1112  return (res);
1113 }
1114 
1115 int totemudpu_recv_flush (void *udpu_context)
1116 {
1117  int res = 0;
1118 
1119  return (res);
1120 }
1121 
1122 int totemudpu_send_flush (void *udpu_context)
1123 {
1124  int res = 0;
1125 
1126  return (res);
1127 }
1128 
1130  void *udpu_context,
1131  const void *msg,
1132  unsigned int msg_len)
1133 {
1134  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1135  int res = 0;
1136 
1137  ucast_sendmsg (instance, &instance->token_target, msg, msg_len);
1138 
1139  return (res);
1140 }
1142  void *udpu_context,
1143  const void *msg,
1144  unsigned int msg_len)
1145 {
1146  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1147  int res = 0;
1148 
1149  mcast_sendmsg (instance, msg, msg_len, 0);
1150 
1151  return (res);
1152 }
1153 
1155  void *udpu_context,
1156  const void *msg,
1157  unsigned int msg_len)
1158 {
1159  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1160  int res = 0;
1161 
1162  mcast_sendmsg (instance, msg, msg_len, 1);
1163 
1164  return (res);
1165 }
1166 
1167 extern int totemudpu_iface_check (void *udpu_context)
1168 {
1169  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1170  int res = 0;
1171 
1172  timer_function_netif_check_timeout (instance);
1173 
1174  return (res);
1175 }
1176 
1177 extern void totemudpu_net_mtu_adjust (void *udpu_context, struct totem_config *totem_config)
1178 {
1179 
1180  assert(totem_config->interface_count > 0);
1181 
1182  totem_config->net_mtu -= crypto_sec_header_size(totem_config->crypto_cipher_type,
1183  totem_config->crypto_hash_type) +
1185 }
1186 
1187 const char *totemudpu_iface_print (void *udpu_context) {
1188  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1189  const char *ret_char;
1190 
1191  ret_char = totemip_print (&instance->my_id);
1192 
1193  return (ret_char);
1194 }
1195 
1197  void *udpu_context,
1198  struct totem_ip_address *addr)
1199 {
1200  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1201  int res = 0;
1202 
1203  memcpy (addr, &instance->my_id, sizeof (struct totem_ip_address));
1204 
1205  return (res);
1206 }
1207 
1209  void *udpu_context,
1210  const struct totem_ip_address *token_target)
1211 {
1212  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1213  int res = 0;
1214 
1215  memcpy (&instance->token_target, token_target,
1216  sizeof (struct totem_ip_address));
1217 
1218  instance->totemudpu_target_set_completed (instance->context);
1219 
1220  return (res);
1221 }
1222 
1224  void *udpu_context)
1225 {
1226  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1227  unsigned int res;
1228  struct sockaddr_storage system_from;
1229  struct msghdr msg_recv;
1230  struct pollfd ufd;
1231  int nfds, i;
1232  int msg_processed = 0;
1233  int sock;
1234 
1235  /*
1236  * Receive datagram
1237  */
1238  msg_recv.msg_name = &system_from;
1239  msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
1240  msg_recv.msg_iov = &instance->totemudpu_iov_recv;
1241  msg_recv.msg_iovlen = 1;
1242 #ifdef HAVE_MSGHDR_CONTROL
1243  msg_recv.msg_control = 0;
1244 #endif
1245 #ifdef HAVE_MSGHDR_CONTROLLEN
1246  msg_recv.msg_controllen = 0;
1247 #endif
1248 #ifdef HAVE_MSGHDR_FLAGS
1249  msg_recv.msg_flags = 0;
1250 #endif
1251 #ifdef HAVE_MSGHDR_ACCRIGHTS
1252  msg_recv.msg_accrights = NULL;
1253 #endif
1254 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
1255  msg_recv.msg_accrightslen = 0;
1256 #endif
1257 
1258  for (i = 0; i < 2; i++) {
1259  sock = -1;
1260  if (i == 0) {
1261  if (instance->netif_bind_state == BIND_STATE_REGULAR) {
1262  sock = instance->token_socket;
1263  } else {
1264  continue;
1265  }
1266  }
1267  if (i == 1) {
1268  sock = instance->local_loop_sock[0];
1269  }
1270  assert(sock != -1);
1271 
1272  do {
1273  ufd.fd = sock;
1274  ufd.events = POLLIN;
1275  nfds = poll (&ufd, 1, 0);
1276  if (nfds == 1 && ufd.revents & POLLIN) {
1277  res = recvmsg (sock, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
1278  if (res != -1) {
1279  msg_processed = 1;
1280  } else {
1281  msg_processed = -1;
1282  }
1283  }
1284  } while (nfds == 1);
1285  }
1286 
1287  return (msg_processed);
1288 }
1289 
1290 static int totemudpu_create_sending_socket(
1291  void *udpu_context,
1292  const struct totem_ip_address *member)
1293 {
1294  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1295  int fd;
1296  int res;
1297  unsigned int sendbuf_size;
1298  unsigned int optlen = sizeof (sendbuf_size);
1299  struct sockaddr_storage sockaddr;
1300  int addrlen;
1301 
1302  fd = socket (member->family, SOCK_DGRAM, 0);
1303  if (fd == -1) {
1304  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1305  "Could not create socket for new member");
1306  return (-1);
1307  }
1308  totemip_nosigpipe (fd);
1309  res = fcntl (fd, F_SETFL, O_NONBLOCK);
1310  if (res == -1) {
1311  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1312  "Could not set non-blocking operation on token socket");
1313  goto error_close_fd;
1314  }
1315 
1316  /*
1317  * These sockets are used to send multicast messages, so their buffers
1318  * should be large
1319  */
1320  sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
1321  res = setsockopt (fd, SOL_SOCKET, SO_SNDBUF,
1322  &sendbuf_size, optlen);
1323  if (res == -1) {
1324  LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
1325  "Could not set sendbuf size");
1326  /*
1327  * Fail in setting sendbuf size is not fatal -> don't exit
1328  */
1329  }
1330 
1331  /*
1332  * Bind to sending interface
1333  */
1334  totemip_totemip_to_sockaddr_convert(&instance->my_id, 0, &sockaddr, &addrlen);
1335  res = bind (fd, (struct sockaddr *)&sockaddr, addrlen);
1336  if (res == -1) {
1337  LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
1338  "bind token socket failed");
1339  goto error_close_fd;
1340  }
1341 
1342  return (fd);
1343 
1344 error_close_fd:
1345  close(fd);
1346  return (-1);
1347 }
1348 
1350  void *udpu_context,
1351  const struct totem_ip_address *member)
1352 {
1353  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1354 
1355  struct totemudpu_member *new_member;
1356 
1357  new_member = malloc (sizeof (struct totemudpu_member));
1358  if (new_member == NULL) {
1359  return (-1);
1360  }
1361 
1362  memset(new_member, 0, sizeof(*new_member));
1363 
1364  log_printf (LOGSYS_LEVEL_NOTICE, "adding new UDPU member {%s}",
1365  totemip_print(member));
1366  list_init (&new_member->list);
1367  list_add_tail (&new_member->list, &instance->member_list);
1368  memcpy (&new_member->member, member, sizeof (struct totem_ip_address));
1369  new_member->fd = totemudpu_create_sending_socket(udpu_context, member);
1370  new_member->active = 0;
1371 
1372  return (0);
1373 }
1374 
1376  void *udpu_context,
1377  const struct totem_ip_address *token_target)
1378 {
1379  int found = 0;
1380  struct list_head *list;
1381  struct totemudpu_member *member;
1382 
1383  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1384 
1385  /*
1386  * Find the member to remove and close its socket
1387  */
1388  for (list = instance->member_list.next;
1389  list != &instance->member_list;
1390  list = list->next) {
1391 
1392  member = list_entry (list,
1393  struct totemudpu_member,
1394  list);
1395 
1396  if (totemip_compare (token_target, &member->member)==0) {
1398  "removing UDPU member {%s}",
1399  totemip_print(&member->member));
1400 
1401  if (member->fd > 0) {
1403  "Closing socket to: {%s}",
1404  totemip_print(&member->member));
1405  qb_loop_poll_del (instance->totemudpu_poll_handle,
1406  member->fd);
1407  close (member->fd);
1408  }
1409  found = 1;
1410  break;
1411  }
1412  }
1413 
1414  /*
1415  * Delete the member from the list
1416  */
1417  if (found) {
1418  list_del (list);
1419  }
1420 
1421  instance = NULL;
1422  return (0);
1423 }
1424 
1426  void *udpu_context)
1427 {
1428  struct list_head *list;
1429  struct totemudpu_member *member;
1430 
1431  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1432 
1433  for (list = instance->member_list.next;
1434  list != &instance->member_list;
1435  list = list->next) {
1436 
1437  member = list_entry (list,
1438  struct totemudpu_member,
1439  list);
1440 
1441  if (member->fd > 0) {
1442  close (member->fd);
1443  }
1444 
1445  member->fd = totemudpu_create_sending_socket(udpu_context, &member->member);
1446  }
1447 
1448  return (0);
1449 }
1450 
1452  void *udpu_context,
1453  const struct totem_ip_address *member_ip,
1454  int active)
1455 {
1456  struct list_head *list;
1457  struct totemudpu_member *member;
1458  int addr_found = 0;
1459 
1460  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1461 
1462  /*
1463  * Find the member to set active flag
1464  */
1465  for (list = instance->member_list.next; list != &instance->member_list; list = list->next) {
1466  member = list_entry (list, struct totemudpu_member, list);
1467 
1468  if (totemip_compare (member_ip, &member->member) == 0) {
1470  "Marking UDPU member %s %s",
1471  totemip_print(&member->member),
1472  (active ? "active" : "inactive"));
1473 
1474  member->active = active;
1475  addr_found = 1;
1476 
1477  break;
1478  }
1479  }
1480 
1481  if (!addr_found) {
1483  "Can't find UDPU member %s (should be marked as %s)",
1484  totemip_print(member_ip),
1485  (active ? "active" : "inactive"));
1486  }
1487 
1488  return (0);
1489 }
1490 
1491 static void timer_function_merge_detect_timeout (
1492  void *data)
1493 {
1494  struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
1495 
1496  if (instance->merge_detect_messages_sent_before_timeout == 0) {
1497  instance->send_merge_detect_message = 1;
1498  }
1499 
1501 
1502  totemudpu_start_merge_detect_timeout(instance);
1503 }
1504 
1505 static void totemudpu_start_merge_detect_timeout(
1506  void *udpu_context)
1507 {
1508  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1509 
1510  qb_loop_timer_add(instance->totemudpu_poll_handle,
1511  QB_LOOP_MED,
1512  instance->totem_config->merge_timeout * 2 * QB_TIME_NS_IN_MSEC,
1513  (void *)instance,
1514  timer_function_merge_detect_timeout,
1515  &instance->timer_merge_detect_timeout);
1516 
1517 }
1518 
1519 static void totemudpu_stop_merge_detect_timeout(
1520  void *udpu_context)
1521 {
1522  struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
1523 
1524  qb_loop_timer_del(instance->totemudpu_poll_handle,
1525  instance->timer_merge_detect_timeout);
1526 }
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:1208
const char * totemip_print(const struct totem_ip_address *addr)
Definition: totemip.c:263
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:836
struct totemudpu_instance * instance
Definition: totemudpu.c:194
#define NETIF_STATE_REPORT_DOWN
Definition: totemudpu.c:85
int totemip_compare(const void *a, const void *b)
Definition: totemip.c:157
#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:1093
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:94
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
void totemip_copy(struct totem_ip_address *addr1, const struct totem_ip_address *addr2)
Definition: totemip.c:122
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:1187
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:454
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:1088
void * totemudpu_buffer_alloc(void)
Definition: totemudpu.c:1083
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:1154
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:1129
struct totem_ip_address boundto
Definition: totem.h:69
typedef __attribute__
size_t totemip_udpip_header_size(int family)
Definition: totemip.c:545
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:241
#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:1375
int totemudpu_member_set_active(void *udpu_context, const struct totem_ip_address *member_ip, int active)
Definition: totemudpu.c:1451
#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:271
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:1223
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:976
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:1177
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:1141
int totemudpu_send_flush(void *udpu_context)
Definition: totemudpu.c:1122
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:1115
unsigned int msg_len
Definition: totemudp.c:197
int totemudpu_member_add(void *udpu_context, const struct totem_ip_address *member)
Definition: totemudpu.c:1349
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:1196
int totemudpu_member_list_rebind_ip(void *udpu_context)
Definition: totemudpu.c:1425
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:1167
int totemudpu_log_level_notice
Definition: totemudpu.c:131