40 #include <sys/types.h>
42 #include <sys/socket.h>
45 #include <sys/ioctl.h>
46 #include <sys/param.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
61 #include <qb/qbdefs.h>
62 #include <qb/qbloop.h>
67 #define LOGSYS_UTILS_ONLY 1
80 #define MSG_NOSIGNAL 0
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
87 #define BIND_STATE_UNBOUND 0
88 #define BIND_STATE_REGULAR 1
89 #define BIND_STATE_LOOPBACK 2
114 unsigned int msg_len);
140 const char *
function,
197 static int totemudpu_build_sockets (
202 static int totemudpu_create_sending_socket(
209 static void totemudpu_start_merge_detect_timeout(
212 static void totemudpu_stop_merge_detect_timeout(
233 #define log_printf(level, format, args...) \
235 instance->totemudpu_log_printf ( \
236 level, instance->totemudpu_subsys_id, \
237 __FUNCTION__, __FILE__, __LINE__, \
238 (const char *)format, ##args); \
240 #define LOGSYS_PERROR(err_num, level, fmt, args...) \
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); \
252 const char *cipher_type,
253 const char *hash_type)
260 static inline void ucast_sendmsg (
264 unsigned int msg_len)
266 struct msghdr msg_ucast;
270 struct sockaddr_storage sockaddr;
286 (
const unsigned char *)msg,
289 &buf_out_len) != 0) {
294 iovec.iov_base = (
void *)buf_out;
295 iovec.iov_len = buf_out_len;
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;
310 #ifdef HAVE_MSGHDR_CONTROLLEN
311 msg_ucast.msg_controllen = 0;
313 #ifdef HAVE_MSGHDR_FLAGS
314 msg_ucast.msg_flags = 0;
316 #ifdef HAVE_MSGHDR_ACCRIGHTS
317 msg_ucast.msg_accrights = NULL;
319 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
320 msg_ucast.msg_accrightslen = 0;
327 msg_ucast.msg_name = NULL;
328 msg_ucast.msg_namelen = 0;
339 "sendmsg(ucast) failed (non-critical)");
343 static inline void mcast_sendmsg (
346 unsigned int msg_len,
349 struct msghdr msg_mcast;
354 struct sockaddr_storage sockaddr;
370 (
const unsigned char *)msg,
373 &buf_out_len) != 0) {
378 iovec.iov_base = (
void *)buf_out;
379 iovec.iov_len = buf_out_len;
381 memset(&msg_mcast, 0,
sizeof(msg_mcast));
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;
410 #ifdef HAVE_MSGHDR_CONTROLLEN
411 msg_mcast.msg_controllen = 0;
413 #ifdef HAVE_MSGHDR_FLAGS
414 msg_mcast.msg_flags = 0;
416 #ifdef HAVE_MSGHDR_ACCRIGHTS
417 msg_mcast.msg_accrights = NULL;
419 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
420 msg_mcast.msg_accrightslen = 0;
430 "sendmsg(mcast) failed (non-critical)");
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;
454 #ifdef HAVE_MSGHDR_CONTROLLEN
455 msg_mcast.msg_controllen = 0;
457 #ifdef HAVE_MSGHDR_FLAGS
458 msg_mcast.msg_flags = 0;
460 #ifdef HAVE_MSGHDR_ACCRIGHTS
461 msg_mcast.msg_accrights = NULL;
463 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
464 msg_mcast.msg_accrightslen = 0;
471 "sendmsg(local mcast loop) failed (non-critical)");
495 totemudpu_stop_merge_detect_timeout(instance);
501 const void *udpu_context,
502 const struct sockaddr *sa)
529 static int net_deliver_fn (
535 struct msghdr msg_recv;
540 int truncated_packet;
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;
554 #ifdef HAVE_MSGHDR_CONTROLLEN
555 msg_recv.msg_controllen = 0;
557 #ifdef HAVE_MSGHDR_FLAGS
558 msg_recv.msg_flags = 0;
560 #ifdef HAVE_MSGHDR_ACCRIGHTS
561 msg_recv.msg_accrights = NULL;
563 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
564 msg_recv.msg_accrightslen = 0;
567 bytes_received = recvmsg (fd, &msg_recv,
MSG_NOSIGNAL | MSG_DONTWAIT);
568 if (bytes_received == -1) {
574 truncated_packet = 0;
576 #ifdef HAVE_MSGHDR_FLAGS
577 if (msg_recv.msg_flags & MSG_TRUNC) {
578 truncated_packet = 1;
586 truncated_packet = 1;
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 "
600 find_member_by_sockaddr(instance, (
const struct sockaddr *)&
system_from) == NULL) {
615 "Invalid packet data");
619 iovec->iov_len = bytes_received;
633 static int netif_determine (
643 interface_up, interface_num,
655 static void timer_function_netif_check_timeout (
665 netif_determine (instance,
668 &interface_up, &interface_num);
674 interface_up == 0) ||
678 interface_up == 1)) {
684 timer_function_netif_check_timeout,
700 if (interface_up == 0) {
703 "One of your ip addresses are now bound to localhost. "
704 "Corosync would not work correctly.");
720 timer_function_netif_check_timeout,
731 totemudpu_build_sockets (instance,
739 POLLIN, instance, net_deliver_fn);
750 "The network interface [%s] is now up.",
763 timer_function_netif_check_timeout,
770 "The network interface is down.");
780 static void totemudpu_traffic_control_set(
struct totemudpu_instance *instance,
int sock)
785 if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio,
sizeof(
int))) {
787 "Could not set traffic priority");
792 static int totemudpu_build_sockets_ip (
798 struct sockaddr_storage sockaddr;
801 unsigned int recvbuf_size;
802 unsigned int optlen =
sizeof (recvbuf_size);
803 unsigned int retries = 0;
816 res = fcntl (instance->
token_socket, F_SETFL, O_NONBLOCK);
819 "Could not set non-blocking operation on token socket");
829 res = bind (instance->
token_socket, (
struct sockaddr *)&sockaddr, addrlen);
834 "bind token socket failed");
854 res = setsockopt (instance->
token_socket, SOL_SOCKET, SO_RCVBUF,
855 &recvbuf_size, optlen);
858 "Could not set recvbuf size");
864 static int totemudpu_build_local_sockets(
868 unsigned int sendbuf_size;
869 unsigned int recvbuf_size;
870 unsigned int optlen =
sizeof (sendbuf_size);
876 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, instance->
local_loop_sock) == -1) {
882 for (i = 0; i < 2; i++) {
887 "Could not set non-blocking operation on multicast socket");
895 res = setsockopt (instance->
local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
898 "Unable to set SO_RCVBUF size on UDP local mcast loop socket");
901 res = setsockopt (instance->
local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
904 "Unable to set SO_SNDBUF size on UDP local mcast loop socket");
908 res = getsockopt (instance->
local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
911 "Local receive multicast loop socket recv buffer size (%d bytes).", recvbuf_size);
914 res = getsockopt (instance->
local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
917 "Local transmit multicast loop socket send buffer size (%d bytes).", sendbuf_size);
923 static int totemudpu_build_sockets (
935 res = netif_determine (instance,
947 res = totemudpu_build_sockets_ip (instance,
948 bindnet_address, bound_to, interface_num);
953 "Unable to create sockets, exiting");
958 totemudpu_traffic_control_set(instance, instance->
token_socket);
977 qb_loop_t *poll_handle,
987 unsigned int msg_len),
989 void (*iface_change_fn) (
993 void (*target_set_completed) (
999 if (instance == NULL) {
1003 totemudpu_instance_initialize (instance);
1055 if (totemudpu_build_local_sockets(instance) == -1) {
1064 POLLIN, instance, net_deliver_fn);
1072 100*QB_TIME_NS_IN_MSEC,
1074 timer_function_netif_check_timeout,
1077 totemudpu_start_merge_detect_timeout((
void*)instance);
1079 *udpu_context = instance;
1095 int processor_count)
1103 if (processor_count == 1) {
1108 timer_function_netif_check_timeout,
1132 unsigned int msg_len)
1137 ucast_sendmsg (instance, &instance->
token_target, msg, msg_len);
1144 unsigned int msg_len)
1149 mcast_sendmsg (instance, msg, msg_len, 0);
1157 unsigned int msg_len)
1162 mcast_sendmsg (instance, msg, msg_len, 1);
1172 timer_function_netif_check_timeout (instance);
1189 const char *ret_char;
1228 struct sockaddr_storage system_from;
1229 struct msghdr msg_recv;
1232 int msg_processed = 0;
1239 msg_recv.msg_namelen =
sizeof (
struct sockaddr_storage);
1241 msg_recv.msg_iovlen = 1;
1242 #ifdef HAVE_MSGHDR_CONTROL
1243 msg_recv.msg_control = 0;
1245 #ifdef HAVE_MSGHDR_CONTROLLEN
1246 msg_recv.msg_controllen = 0;
1248 #ifdef HAVE_MSGHDR_FLAGS
1249 msg_recv.msg_flags = 0;
1251 #ifdef HAVE_MSGHDR_ACCRIGHTS
1252 msg_recv.msg_accrights = NULL;
1254 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
1255 msg_recv.msg_accrightslen = 0;
1258 for (i = 0; i < 2; i++) {
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);
1284 }
while (nfds == 1);
1287 return (msg_processed);
1290 static int totemudpu_create_sending_socket(
1297 unsigned int sendbuf_size;
1298 unsigned int optlen =
sizeof (sendbuf_size);
1299 struct sockaddr_storage sockaddr;
1302 fd = socket (member->
family, SOCK_DGRAM, 0);
1305 "Could not create socket for new member");
1309 res = fcntl (fd, F_SETFL, O_NONBLOCK);
1312 "Could not set non-blocking operation on token socket");
1313 goto error_close_fd;
1321 res = setsockopt (fd, SOL_SOCKET, SO_SNDBUF,
1322 &sendbuf_size, optlen);
1325 "Could not set sendbuf size");
1335 res = bind (fd, (
struct sockaddr *)&sockaddr, addrlen);
1338 "bind token socket failed");
1339 goto error_close_fd;
1358 if (new_member == NULL) {
1362 memset(new_member, 0,
sizeof(*new_member));
1366 list_init (&new_member->
list);
1369 new_member->
fd = totemudpu_create_sending_socket(udpu_context, member);
1390 list = list->
next) {
1398 "removing UDPU member {%s}",
1401 if (member->
fd > 0) {
1403 "Closing socket to: {%s}",
1435 list = list->
next) {
1441 if (member->
fd > 0) {
1445 member->
fd = totemudpu_create_sending_socket(udpu_context, &member->
member);
1470 "Marking UDPU member %s %s",
1472 (active ?
"active" :
"inactive"));
1483 "Can't find UDPU member %s (should be marked as %s)",
1485 (active ?
"active" :
"inactive"));
1491 static void timer_function_merge_detect_timeout (
1502 totemudpu_start_merge_detect_timeout(instance);
1505 static void totemudpu_start_merge_detect_timeout(
1514 timer_function_merge_detect_timeout,
1519 static void totemudpu_stop_merge_detect_timeout(
unsigned int clear_node_high_bit
#define BIND_STATE_UNBOUND
#define NETIF_STATE_REPORT_UP
struct totem_config * totem_config
struct totem_ip_address member
unsigned int my_memb_entries
void(* totemudpu_iface_change_fn)(void *context, const struct totem_ip_address *iface_address)
struct totem_interface * interfaces
unsigned int interface_count
size_t crypto_sec_header_size(const char *crypto_cipher_type, const char *crypto_hash_type)
The totem_ip_address struct.
void(*) void udpu_context)
int totemudpu_token_target_set(void *udpu_context, const struct totem_ip_address *token_target)
const char * totemip_print(const struct totem_ip_address *addr)
struct totem_ip_address my_id
size_t crypto_get_current_sec_header_size(const struct crypto_instance *instance)
struct totemudpu_instance * instance
#define NETIF_STATE_REPORT_DOWN
int totemip_compare(const void *a, const void *b)
#define log_printf(level, format, args...)
unsigned char private_key[TOTEM_PRIVATE_KEY_LEN]
int totemudpu_processor_count_set(void *udpu_context, int processor_count)
unsigned char addr[TOTEMIP_ADDRLEN]
int totemudpu_log_level_security
int totemip_sa_equal(const struct totem_ip_address *totem_ip, const struct sockaddr *sa)
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)
void totemip_copy(struct totem_ip_address *addr1, const struct totem_ip_address *addr2)
unsigned int downcheck_timeout
unsigned int private_key_len
char iov_buffer[FRAME_SIZE_MAX]
qb_loop_timer_handle timer_merge_detect_timeout
int send_merge_detect_message
#define totemip_nosigpipe(s)
int totemudpu_log_level_warning
int totemudpu_log_level_debug
const char * totemudpu_iface_print(void *udpu_context)
struct iovec totemudpu_iov_recv
unsigned int block_unlisted_ips
#define BIND_STATE_REGULAR
int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num, int mask_high_bit)
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)
void totemudpu_buffer_release(void *ptr)
void * totemudpu_buffer_alloc(void)
unsigned int merge_detect_messages_sent_before_timeout
qb_loop_t * totemudpu_poll_handle
int totemudpu_mcast_noflush_send(void *udpu_context, const void *msg, unsigned int msg_len)
void(* totemudpu_deliver_fn)(void *context, const void *msg, unsigned int msg_len)
#define BIND_RETRIES_INTERVAL
struct totem_ip_address token_target
int totemudpu_crypto_set(void *udpu_context, const char *cipher_type, const char *hash_type)
#define LOGSYS_LEVEL_DEBUG
struct totem_interface * totem_interface
int totemudpu_token_send(void *udpu_context, const void *msg, unsigned int msg_len)
struct totem_ip_address boundto
size_t totemip_udpip_header_size(int family)
struct list_head member_list
void(* log_printf)(int level, int subsys, const char *function_name, const char *file_name, int file_line, const char *format,...) __attribute__((format(printf
struct timeval stats_tv_start
qb_loop_timer_handle timer_netif_check_timeout
void(* totemudpu_target_set_completed)(void *context)
#define BIND_STATE_LOOPBACK
const char * totemip_sa_print(const struct sockaddr *sa)
#define MCAST_SOCKET_BUFFER_SIZE
#define PROCESSOR_COUNT_MAX
int crypto_authenticate_and_decrypt(struct crypto_instance *instance, unsigned char *buf, int *buf_len)
int totemudpu_member_remove(void *udpu_context, const struct totem_ip_address *token_target)
int totemudpu_member_set_active(void *udpu_context, const struct totem_ip_address *member_ip, int active)
#define LOGSYS_LEVEL_CRIT
#define list_entry(ptr, type, member)
int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
struct totem_logging_configuration totem_logging_configuration
#define LOGSYS_LEVEL_NOTICE
int totemudpu_recv_mcast_empty(void *udpu_context)
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.
struct srp_addr system_from
char * crypto_cipher_type
int totemudpu_log_level_error
unsigned int merge_timeout
void totemudpu_net_mtu_adjust(void *udpu_context, struct totem_config *totem_config)
struct totem_ip_address bindnet
int totemudpu_mcast_flush_send(void *udpu_context, const void *msg, unsigned int msg_len)
int totemudpu_send_flush(void *udpu_context)
int totemudpu_finalize(void *udpu_context)
struct crypto_instance * crypto_inst
int totemudpu_recv_flush(void *udpu_context)
int totemudpu_member_add(void *udpu_context, const struct totem_ip_address *member)
#define LOGSYS_PERROR(err_num, level, fmt, args...)
int totemudpu_iface_get(void *udpu_context, struct totem_ip_address *addr)
int totemudpu_member_list_rebind_ip(void *udpu_context)
void(* totemudpu_log_printf)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf
int totemudpu_iface_check(void *udpu_context)
int totemudpu_log_level_notice