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
113 unsigned int msg_len);
139 const char *
function,
188 static int totemudpu_build_sockets (
193 static int totemudpu_create_sending_socket(
220 #define log_printf(level, format, args...) \
222 instance->totemudpu_log_printf ( \
223 level, instance->totemudpu_subsys_id, \
224 __FUNCTION__, __FILE__, __LINE__, \
225 (const char *)format, ##args); \
227 #define LOGSYS_PERROR(err_num, level, fmt, args...) \
229 char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
230 const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
231 instance->totemudpu_log_printf ( \
232 level, instance->totemudpu_subsys_id, \
233 __FUNCTION__, __FILE__, __LINE__, \
234 fmt ": %s (%d)", ##args, _error_ptr, err_num); \
239 const char *cipher_type,
240 const char *hash_type)
247 static inline void ucast_sendmsg (
251 unsigned int msg_len)
253 struct msghdr msg_ucast;
257 struct sockaddr_storage sockaddr;
266 (
const unsigned char *)msg,
269 &buf_out_len) != 0) {
274 iovec.iov_base = (
void *)buf_out;
275 iovec.iov_len = buf_out_len;
282 memset(&msg_ucast, 0,
sizeof(msg_ucast));
283 msg_ucast.msg_name = &sockaddr;
284 msg_ucast.msg_namelen = addrlen;
285 msg_ucast.msg_iov = (
void *)&iovec;
286 msg_ucast.msg_iovlen = 1;
287 #ifdef HAVE_MSGHDR_CONTROL
288 msg_ucast.msg_control = 0;
290 #ifdef HAVE_MSGHDR_CONTROLLEN
291 msg_ucast.msg_controllen = 0;
293 #ifdef HAVE_MSGHDR_FLAGS
294 msg_ucast.msg_flags = 0;
296 #ifdef HAVE_MSGHDR_ACCRIGHTS
297 msg_ucast.msg_accrights = NULL;
299 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
300 msg_ucast.msg_accrightslen = 0;
311 "sendmsg(ucast) failed (non-critical)");
315 static inline void mcast_sendmsg (
318 unsigned int msg_len)
320 struct msghdr msg_mcast;
325 struct sockaddr_storage sockaddr;
335 (
const unsigned char *)msg,
338 &buf_out_len) != 0) {
343 iovec.iov_base = (
void *)buf_out;
344 iovec.iov_len = buf_out_len;
346 memset(&msg_mcast, 0,
sizeof(msg_mcast));
360 msg_mcast.msg_name = &sockaddr;
361 msg_mcast.msg_namelen = addrlen;
362 msg_mcast.msg_iov = (
void *)&iovec;
363 msg_mcast.msg_iovlen = 1;
364 #ifdef HAVE_MSGHDR_CONTROL
365 msg_mcast.msg_control = 0;
367 #ifdef HAVE_MSGHDR_CONTROLLEN
368 msg_mcast.msg_controllen = 0;
370 #ifdef HAVE_MSGHDR_FLAGS
371 msg_mcast.msg_flags = 0;
373 #ifdef HAVE_MSGHDR_ACCRIGHTS
374 msg_mcast.msg_accrights = NULL;
376 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
377 msg_mcast.msg_accrightslen = 0;
387 "sendmsg(mcast) failed (non-critical)");
407 static int net_deliver_fn (
413 struct msghdr msg_recv;
425 msg_recv.msg_namelen =
sizeof (
struct sockaddr_storage);
426 msg_recv.msg_iov = iovec;
427 msg_recv.msg_iovlen = 1;
428 #ifdef HAVE_MSGHDR_CONTROL
429 msg_recv.msg_control = 0;
431 #ifdef HAVE_MSGHDR_CONTROLLEN
432 msg_recv.msg_controllen = 0;
434 #ifdef HAVE_MSGHDR_FLAGS
435 msg_recv.msg_flags = 0;
437 #ifdef HAVE_MSGHDR_ACCRIGHTS
438 msg_recv.msg_accrights = NULL;
440 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
441 msg_recv.msg_accrightslen = 0;
444 bytes_received = recvmsg (fd, &msg_recv,
MSG_NOSIGNAL | MSG_DONTWAIT);
445 if (bytes_received == -1) {
459 "Invalid packet data");
463 iovec->iov_len = bytes_received;
477 static int netif_determine (
487 interface_up, interface_num,
499 static void timer_function_netif_check_timeout (
510 netif_determine (instance,
513 &interface_up, &interface_num);
519 interface_up == 0) ||
523 interface_up == 1)) {
529 timer_function_netif_check_timeout,
544 if (interface_up == 0) {
549 bind_address = &localhost;
558 timer_function_netif_check_timeout,
570 totemudpu_build_sockets (instance,
577 POLLIN, instance, net_deliver_fn);
587 "The network interface [%s] is now up.",
600 timer_function_netif_check_timeout,
607 "The network interface is down.");
617 static void totemudpu_traffic_control_set(
struct totemudpu_instance *instance,
int sock)
622 if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio,
sizeof(
int))) {
624 "Could not set traffic priority");
629 static int totemudpu_build_sockets_ip (
635 struct sockaddr_storage sockaddr;
638 unsigned int recvbuf_size;
639 unsigned int optlen =
sizeof (recvbuf_size);
652 res = fcntl (instance->
token_socket, F_SETFL, O_NONBLOCK);
655 "Could not set non-blocking operation on token socket");
664 res = bind (instance->
token_socket, (
struct sockaddr *)&sockaddr, addrlen);
667 "bind token socket failed");
676 res = setsockopt (instance->
token_socket, SOL_SOCKET, SO_RCVBUF,
677 &recvbuf_size, optlen);
680 "Could not set recvbuf size");
686 static int totemudpu_build_sockets (
698 res = netif_determine (instance,
710 res = totemudpu_build_sockets_ip (instance,
711 bindnet_address, bound_to, interface_num);
714 totemudpu_traffic_control_set(instance, instance->
token_socket);
733 qb_loop_t *poll_handle,
743 unsigned int msg_len),
745 void (*iface_change_fn) (
749 void (*target_set_completed) (
755 if (instance == NULL) {
759 totemudpu_instance_initialize (instance);
817 100*QB_TIME_NS_IN_MSEC,
819 timer_function_netif_check_timeout,
822 *udpu_context = instance;
846 if (processor_count == 1) {
851 timer_function_netif_check_timeout,
875 unsigned int msg_len)
880 ucast_sendmsg (instance, &instance->
token_target, msg, msg_len);
887 unsigned int msg_len)
892 mcast_sendmsg (instance, msg, msg_len);
900 unsigned int msg_len)
905 mcast_sendmsg (instance, msg, msg_len);
915 timer_function_netif_check_timeout (instance);
922 #define UDPIP_HEADER_SIZE (20 + 8)
930 const char *ret_char;
969 struct sockaddr_storage system_from;
970 struct msghdr msg_recv;
973 int msg_processed = 0;
979 msg_recv.msg_namelen =
sizeof (
struct sockaddr_storage);
981 msg_recv.msg_iovlen = 1;
982 #ifdef HAVE_MSGHDR_CONTROL
983 msg_recv.msg_control = 0;
985 #ifdef HAVE_MSGHDR_CONTROLLEN
986 msg_recv.msg_controllen = 0;
988 #ifdef HAVE_MSGHDR_FLAGS
989 msg_recv.msg_flags = 0;
991 #ifdef HAVE_MSGHDR_ACCRIGHTS
992 msg_recv.msg_accrights = NULL;
994 #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
995 msg_recv.msg_accrightslen = 0;
1000 ufd.events = POLLIN;
1001 nfds = poll (&ufd, 1, 0);
1002 if (nfds == 1 && ufd.revents & POLLIN) {
1010 }
while (nfds == 1);
1012 return (msg_processed);
1015 static int totemudpu_create_sending_socket(
1022 unsigned int sendbuf_size;
1023 unsigned int optlen =
sizeof (sendbuf_size);
1024 struct sockaddr_storage sockaddr;
1027 fd = socket (member->
family, SOCK_DGRAM, 0);
1030 "Could not create socket for new member");
1034 res = fcntl (fd, F_SETFL, O_NONBLOCK);
1037 "Could not set non-blocking operation on token socket");
1038 goto error_close_fd;
1046 res = setsockopt (fd, SOL_SOCKET, SO_SNDBUF,
1047 &sendbuf_size, optlen);
1050 "Could not set sendbuf size");
1060 res = bind (fd, (
struct sockaddr *)&sockaddr, addrlen);
1063 "bind token socket failed");
1064 goto error_close_fd;
1083 if (new_member == NULL) {
1088 list_init (&new_member->
list);
1091 new_member->
fd = totemudpu_create_sending_socket(udpu_context, member);
1111 list = list->
next) {
1119 "removing UDPU member {%s}",
1122 if (member->
fd > 0) {
1124 "Closing socket to: {%s}",
1156 list = list->
next) {
1162 if (member->
fd > 0) {
1166 member->
fd = totemudpu_create_sending_socket(udpu_context, &member->
member);