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