Attatch GIO channel to ARES socket to check event 10/200510/8
authorYu <jiung.yu@samsung.com>
Tue, 26 Feb 2019 04:33:59 +0000 (13:33 +0900)
committerYu <jiung.yu@samsung.com>
Thu, 7 Mar 2019 01:05:23 +0000 (10:05 +0900)
Change-Id: Id379c6da18862186c70f0df8a131bbac6bc510ec
Signed-off-by: Yu Jiung <jiung.yu@samsung.com>
src/inm-dns-lookup.c
src/inm-manager.c

index 076c839e4bb2c43eebf16bed0b8c4ba3bf9ced3b..2ccaa59062603098c92aa9e8b334c0b44b1ba50b 100644 (file)
 #define ARES_DEFAULT_TRY 4
 #define DEFAULT_TEST_URL "www.tizen.org"
 
+typedef enum {
+       INM_SOCK_TYPE_READ,
+       INM_SOCK_TYPE_WRITE,
+} inm_sock_type_e;
+
+typedef struct {
+       ares_channel ares_ch;
+       inm_sock_type_e sock_type;
+       ares_socket_t fd;
+       GIOChannel *sock_io_channel;
+       guint sock_source_id;
+} inm_gio_channel_s;
+
 typedef struct {
        ares_channel channel;
        struct ares_options *ch_options;
+       GSList *gio_data_list;
        guint timer_source_id;
+       gboolean is_lookup_finished;
        inm_default_dns_lookup_callback cb;
        gpointer cb_user_data;
 } inm_dns_lookup_s;
 
 static inm_dns_lookup_s *g_default_dns_lookup_data;
 
-static inline void __destroy_default_dns_lookup_data();
+static void __destroy_sock_gio_channel(gpointer data)
+{
+       inm_gio_channel_s *gio_channel;
+       if (!data)
+               return;
+
+       gio_channel = (inm_gio_channel_s *)data;
+       INM_LOGI("Destroy %d", gio_channel->fd);
+       inm_util_destroy_gio_channel(gio_channel->sock_io_channel, FALSE);
+       gio_channel->sock_io_channel = NULL;
+
+       REMOVE_G_SOURCE(gio_channel->sock_source_id);
+
+       g_free(gio_channel);
+}
+
+static inline void __deinit_ares_channel(inm_dns_lookup_s *dns_lookup_data)
+{
+       __INM_FUNC_ENTER__;
+
+       if (!dns_lookup_data) {
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       g_free(dns_lookup_data->ch_options);
+       ares_destroy(dns_lookup_data->channel);
+       dns_lookup_data->channel = NULL;
+
+       __INM_FUNC_EXIT__;
+       return;
+}
+
+static inline void __destroy_default_dns_lookup_data()
+{
+       inm_dns_lookup_s *dns_lookup_data;
+
+       __INM_FUNC_ENTER__;
+       if (!g_default_dns_lookup_data) {
+               __INM_FUNC_EXIT__;
+               return;
+       }
+       dns_lookup_data = g_default_dns_lookup_data;
+       g_default_dns_lookup_data = NULL;
+
+       REMOVE_G_SOURCE(dns_lookup_data->timer_source_id);
+
+       g_slist_free_full(dns_lookup_data->gio_data_list,
+                       __destroy_sock_gio_channel);
+
+       __deinit_ares_channel(dns_lookup_data);
+       g_free(dns_lookup_data);
+
+       __INM_FUNC_EXIT__;
+       return;
+}
+
+static gboolean __sock_channel_io_cb(GIOChannel *source,
+                                       GIOCondition condition, gpointer data)
+{
+       inm_gio_channel_s *gio_channel;
+       ares_socket_t read_fd = ARES_SOCKET_BAD;
+       ares_socket_t write_fd = ARES_SOCKET_BAD;
+
+       __INM_FUNC_ENTER__;
+       if (!g_default_dns_lookup_data || !data) {
+               INM_LOGI("default DNS lookup not valid");
+               return FALSE;
+       }
+
+       gio_channel = (inm_gio_channel_s *)data;
+       if (condition & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+               INM_LOGI("GIO condition error for %d", gio_channel->fd);
+               gio_channel->sock_io_channel = 0;
+               return FALSE;
+       }
+
+       if (gio_channel->sock_type == INM_SOCK_TYPE_READ)
+               read_fd = gio_channel->fd;
+       else
+               write_fd = gio_channel->fd;
+
+       /* We should think about when do we call this? */
+       ares_process_fd(gio_channel->ares_ch, read_fd, write_fd);
+
+       if (g_default_dns_lookup_data->is_lookup_finished)
+               __destroy_default_dns_lookup_data();
+
+       __INM_FUNC_EXIT__;
+       return TRUE;
+}
+
+static int __create_sock_gio_channel(inm_dns_lookup_s *dns_lookup, inm_gio_channel_s **gio_channel)
+{
+       inm_gio_channel_s *p_gio_channel = NULL;
+
+       if (!gio_channel)
+               return -1;
+
+       p_gio_channel = g_try_malloc0(sizeof(inm_gio_channel_s));
+       if (!p_gio_channel)
+               return -1;
+
+       dns_lookup->gio_data_list = g_slist_prepend(dns_lookup->gio_data_list,
+                       p_gio_channel);
+
+       *gio_channel = p_gio_channel;
+
+       return 0;
+}
+
+static int __init_sock_gio_channel(inm_sock_type_e sock_type,
+               ares_socket_t fd,
+               inm_gio_channel_s *gio_channel)
+{
+       int ret = 0;
+
+       if (!gio_channel)
+               return -1;
+
+       gio_channel->sock_type = sock_type;
+       gio_channel->fd = fd;
+       ret = inm_util_create_gio_channel(fd, &(gio_channel->sock_io_channel));
+       if (ret != 0)
+               return -1;
+
+       gio_channel->sock_source_id =
+                       g_io_add_watch(gio_channel->sock_io_channel,
+                                       G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+                                       __sock_channel_io_cb,
+                                       (gpointer)gio_channel);
+
+       if (!gio_channel->sock_source_id) {
+               inm_util_destroy_gio_channel(gio_channel->sock_io_channel, FALSE);
+               gio_channel->sock_io_channel = NULL;
+               ret = -1;
+       }
+
+       return ret;
+}
+
+static void __remove_sock_gio_channel(inm_dns_lookup_s *dns_lookup, inm_gio_channel_s *gio_channel)
+{
+       if (!dns_lookup || !gio_channel)
+               return;
+
+       INM_LOGI("Remove %d", gio_channel->fd);
+       dns_lookup->gio_data_list =
+                       g_slist_remove(dns_lookup->gio_data_list, gio_channel);
+}
+
+static gint __compare_sock_fd(gconstpointer dst, gconstpointer user_data)
+{
+       inm_gio_channel_s *gio_channel_dst;
+       gint32 fd;
+
+       if (!dst)
+               return -1;
+
+       fd = GPOINTER_TO_INT(user_data);
+       gio_channel_dst = (inm_gio_channel_s *)dst;
+
+       return (gio_channel_dst->fd - fd);
+}
+
+static inm_gio_channel_s *__find_gio_channel_data(gint32 fd, inm_dns_lookup_s *dns_lookup_data)
+{
+       GSList *list_node = NULL;
+
+       list_node = g_slist_find_custom(dns_lookup_data->gio_data_list,
+                       GINT_TO_POINTER(fd),
+                       __compare_sock_fd);
+
+       return list_node ? (inm_gio_channel_s *)list_node->data : NULL;
+}
+
+static void __sock_state_cb(void *data, int fd, int read, int write)
+{
+       inm_dns_lookup_s *dns_lookup;
+       inm_gio_channel_s *gio_channel;
+       int ret;
+
+       __INM_FUNC_ENTER__;
+       INM_LOGI("Change state fd %d read:%d write:%d\n", fd, read, write);
+       if (!g_default_dns_lookup_data || !data) {
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       dns_lookup = data;
+       gio_channel = __find_gio_channel_data(fd, dns_lookup);
+
+       if (read == 0 && write == 0) {
+               __remove_sock_gio_channel(dns_lookup, gio_channel);
+               __destroy_sock_gio_channel(gio_channel);
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       if (gio_channel) {
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       ret = __create_sock_gio_channel(dns_lookup, &gio_channel);
+       if (ret < 0) {
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       ret = __init_sock_gio_channel(read ? INM_SOCK_TYPE_READ : INM_SOCK_TYPE_WRITE,
+                       fd,
+                       gio_channel);
+       if (ret != 0) {
+               __remove_sock_gio_channel(dns_lookup, gio_channel);
+               __destroy_sock_gio_channel(gio_channel);
+               INM_LOGE("Failed to initialize gio channel");
+               return;
+       }
+       gio_channel->ares_ch = dns_lookup->channel;
+
+       __INM_FUNC_EXIT__;
+       return;
+}
 
 static int __ares_set_opt(inm_dns_lookup_s *lookup_data)
 {
@@ -58,6 +296,8 @@ static int __ares_set_opt(inm_dns_lookup_s *lookup_data)
                return -1;
        }
 
+       p_opts->sock_state_cb = __sock_state_cb;
+       p_opts->sock_state_cb_data = (void *)lookup_data;
        p_opts->timeout = ARES_DEFAULT_TIMEOUT_MS;
        p_opts->tries = ARES_DEFAULT_TRY;
 
@@ -110,48 +350,11 @@ static inline int __create_default_dns_lookup_data()
                return -1;
        }
 
+       dns_lookup_data->is_lookup_finished = FALSE;
        g_default_dns_lookup_data = dns_lookup_data;
        return 0;
 }
 
-static inline void __deinit_ares_channel(inm_dns_lookup_s *dns_lookup_data)
-{
-       __INM_FUNC_ENTER__;
-
-       if (!dns_lookup_data) {
-               __INM_FUNC_EXIT__;
-               return;
-       }
-
-       g_free(dns_lookup_data->ch_options);
-       ares_destroy(dns_lookup_data->channel);
-       dns_lookup_data->channel = NULL;
-
-       __INM_FUNC_EXIT__;
-       return;
-}
-
-static inline void __destroy_default_dns_lookup_data()
-{
-       inm_dns_lookup_s *dns_lookup_data;
-
-       __INM_FUNC_ENTER__;
-       if (!g_default_dns_lookup_data) {
-               __INM_FUNC_EXIT__;
-               return;
-       }
-       dns_lookup_data = g_default_dns_lookup_data;
-       g_default_dns_lookup_data = NULL;
-
-       REMOVE_G_SOURCE(dns_lookup_data->timer_source_id);
-
-       __deinit_ares_channel(dns_lookup_data);
-       g_free(dns_lookup_data);
-
-       __INM_FUNC_EXIT__;
-       return;
-}
-
 static void __ares_host_cb(void *arg, int status, int timeouts, struct hostent *p_host)
 {
        inm_dns_lookup_s *dns_lookup_data;
@@ -175,6 +378,7 @@ static void __ares_host_cb(void *arg, int status, int timeouts, struct hostent *
                        result,
                        p_host ? p_host->h_name : NULL,
                        dns_lookup_data->cb_user_data);
+       dns_lookup_data->is_lookup_finished = TRUE;
 
        __INM_FUNC_EXIT__;
 }
index 32ee0b2d81e8cf5eddda0a0c93498a17dd4c1b5f..b3d968489f54156073d4d402fc12eb4c7855eed7 100644 (file)
@@ -560,10 +560,38 @@ int inm_manager_get_reacher_is_running(gboolean *is_running)
        return INM_MANAGER_ERROR_NONE;
 }
 
+
+static void __default_dns_lookup_callback(
+               inm_dns_lookup_error_e err,
+               gboolean found,
+               gchar *host_name,
+               gpointer user_data)
+{
+       PRINT_LOG("<Host name %s:%s>", host_name, found ? "Found" : "Not Found");
+       inm_gdbus_emit_default_dns_lookup_result(found, host_name);
+
+       return;
+}
+
 int inm_manager_start_default_dns_lookup()
 {
+       int ret = 0;
+
        __INM_FUNC_ENTER__;
 
+       ret = inm_default_dns_lookup_start(__default_dns_lookup_callback, NULL);
+       if (ret != 0) {
+               INM_LOGW("Failed to start dns lookup");
+
+               if (ret == INM_DNS_LOOKUP_ERROR_IN_PROGRESS)
+                       ret = INM_MANAGER_ERROR_IN_PROGRESS;
+               else
+                       ret = -1;
+
+               __INM_FUNC_EXIT__;
+               return ret;
+       }
+
        __INM_FUNC_EXIT__;
        return INM_MANAGER_ERROR_NONE;
 }