Add handler for ARP socket IO error 04/202304/2
authorYu <jiung.yu@samsung.com>
Wed, 27 Mar 2019 04:19:10 +0000 (13:19 +0900)
committerYu <jiung.yu@samsung.com>
Wed, 27 Mar 2019 04:26:49 +0000 (13:26 +0900)
Change-Id: I0818a48dc15bcdcf649f24def33664d3ad944135

include/inm-util.h
packaging/inm-manager.spec
src/inm-arping.c
src/inm-ip-conflict.c
src/inm-util.c

index fcc3b7590fe7839284a256a3c8aaebe91e56dc0b..a22877480713d54cb1e7328b2458b522854805fb 100644 (file)
@@ -65,6 +65,7 @@ extern "C" {
        } while (0)
 
 typedef void (*user_arp_recv_func)(void* ah, void *user_data);
+typedef void (*user_arp_err_func)(void *user_data);
 typedef void (*user_icmp_recv_func)(void* icmp_msg, void *user_data);
 
 #include <netlink/object.h>
@@ -90,6 +91,7 @@ typedef struct {
        guint sock_source_id;
 
        user_arp_recv_func recv_func;
+       user_arp_err_func err_func;
        void *user_data;
 
 } inm_util_arp_data_s;
index aeb9c173a0e9d80015a98b841400110a8e719757..c31a43254d874c367c55237006b7b9bc0d1669a1 100644 (file)
@@ -1,6 +1,6 @@
 Name:       inm-manager
 Summary:    INM(Intelligent Network Monitoring) daemon
-Version:    0.0.19
+Version:    0.0.20
 Release:    1
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
index 68f2a2d5cce972e17900f0b5b0f3ff6e4224a18f..db668b7346a8bd7ffc95d476d2ef2751e1b37202 100644 (file)
@@ -125,10 +125,25 @@ static void __check_arp_receive(arp_message_s* ah, gpointer data)
        return;
 }
 
+static void __check_arp_sock_err(gpointer data)
+{
+       arping_data_s *arping_data;
+
+       if (!data || !g_p_arping_mon)
+               return;
+
+       arping_data = (arping_data_s *)data;
+       INM_LOGE("Socket error occured %d", arping_data->arp_data.sock);
+       util_recover_arp_sock(&(arping_data->arp_data));
+
+       return;
+}
+
 static inline void __init_arping_data(arping_data_s *arping_data)
 {
        arping_data->arp_data.sock = -1;
        arping_data->arp_data.recv_func = (user_arp_recv_func)__check_arp_receive;
+       arping_data->arp_data.err_func = (user_arp_err_func)__check_arp_sock_err;
        arping_data->arp_data.user_data = arping_data;
 
        return;
index a47097da366445f29e80f8b02be027812c9ba70d..94af06a0a40eb3de5d87e1e9a16b11665e899532 100644 (file)
@@ -141,6 +141,18 @@ static void __check_arp_receive(arp_message_s* ah, gpointer data)
        return;
 }
 
+static void __check_arp_sock_err(gpointer data)
+{
+       ip_conflict_data_s *ip_conflict_data;
+
+       if (!data)
+               return;
+
+       ip_conflict_data = (ip_conflict_data_s *)data;
+       INM_LOGE("Socket error occured %d", ip_conflict_data->arp_data.sock);
+       util_recover_arp_sock(&(ip_conflict_data->arp_data));
+}
+
 static inline void __init_ip_conflict_data(ip_conflict_data_s *ip_conflict_data)
 {
        ip_conflict_data->initial_bursts = TRUE;
@@ -149,10 +161,12 @@ static inline void __init_ip_conflict_data(ip_conflict_data_s *ip_conflict_data)
        ip_conflict_data->timeout = g_p_ip_conflict_mon->initial_time;
 
        ip_conflict_data->arp_data.recv_func = (user_arp_recv_func)__check_arp_receive;
+       ip_conflict_data->arp_data.err_func = (user_arp_err_func)__check_arp_sock_err;
        ip_conflict_data->arp_data.user_data = ip_conflict_data;
 
        return;
 }
+
 static void __start_ip_conflict_mon(GQuark key_id,
                gpointer value,
                gpointer user_data)
@@ -261,7 +275,6 @@ int inm_ip_conflict_enable_detection(gchar *if_name, gboolean enable)
                        ip_conflict_data->state = IP_CONFLICT_STATE_UNKNOWN;
                        return INM_IP_CONFLICT_ERROR_OPERATION_FAILED;
                }
-
        } else {
                if (ip_conflict_data->arp_data.sock != -1) {
                        __stop_ip_conflict_mon(if_key, ip_conflict_data, NULL);
index 96718fe487fcf1e6e60afc4518f208b30bb3d23b..3359d016f0317e117c7969e691c45a7bc458b2d8 100644 (file)
@@ -126,35 +126,62 @@ static void __init_ll_addr(struct sockaddr_ll *ll_addr)
        return;
 }
 
-static gboolean __check_arp_receive(GIOChannel *source,
-                                                 GIOCondition condition, gpointer data)
+static void __arp_sock_io_in(GIOChannel *source, inm_util_arp_data_s *arp_data)
 {
-       inm_util_arp_data_s *user_data;
        arp_message_s *ah = NULL;
        gchar buf[ARP_PACKET_SIZE] = {0, };
        gchar *ptr = NULL;
        gsize bytes_read = 0;
        GError *error = NULL;
 
+       INM_LOGI("Read channel");
        if (g_io_channel_read_chars(source, buf, ARP_PACKET_SIZE,
                                &bytes_read, &error) != G_IO_STATUS_NORMAL) {
                INM_LOGE("Failure received arp packet[%d]:[%s]",
                                error->code, error->message);
                g_error_free(error);
-               return TRUE;
+               return;
+       }
+       if (!arp_data) {
+               INM_LOGI("No data");
+               return;
        }
-       if (!data)
-               return TRUE;
 
        ptr = buf + ETH_HLEN;
        ah = (arp_message_s *)ptr;
 
        /* Only handle ARP replies */
-       if (ah->arp_op != htons(ARPOP_REPLY))
-               return TRUE;
+       if (ah->arp_op != htons(ARPOP_REPLY)) {
+               INM_LOGI("OP is not ARP reply from %d", arp_data->sock);
+               return;
+       }
+
+       INM_LOGI("Process from %d", arp_data->sock);
+       arp_data->recv_func(ah, arp_data->user_data);
+
+}
+
+static void __arp_sock_io_err(inm_util_arp_data_s *arp_data)
+{
+       if (!arp_data) {
+               INM_LOGI("No data");
+               return;
+       }
+       arp_data->err_func(arp_data->user_data);
+}
+
+static gboolean __check_arp_receive(GIOChannel *source,
+                                                 GIOCondition condition, gpointer data)
+{
+       inm_util_arp_data_s *arp_data;
 
-       user_data = (inm_util_arp_data_s *)data;
-       user_data->recv_func(ah, user_data->user_data);
+       arp_data = (inm_util_arp_data_s *)data;
+       if (condition == G_IO_IN)
+               __arp_sock_io_in(source, arp_data);
+       else if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+               __arp_sock_io_err(arp_data);
+       else
+               INM_LOGE("unrecognized condition %d", condition);
 
        return TRUE;
 }
@@ -416,8 +443,10 @@ void util_create_arp_sock(inm_util_arp_data_s *arp_data)
 
        arp_data->sock = sock;
        arp_data->sock_source_id =
-                       g_io_add_watch(arp_data->sock_io_channel, G_IO_IN,
-                                       __check_arp_receive, arp_data);
+                       g_io_add_watch(arp_data->sock_io_channel,
+                                       G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+                                       __check_arp_receive,
+                                       arp_data);
 
        INM_LOGI("socket %d source_id %d", sock, arp_data->sock_source_id);