#include "inm-dns-lookup.h"
#define ARES_DEFAULT_TIMEOUT_MS 1000
+#define ARES_DEFAULT_TRY 4
#define DEFAULT_TEST_URL "www.tizen.org"
typedef struct {
+ ares_channel channel;
+ struct ares_options *ch_options;
guint timer_source_id;
inm_default_dns_lookup_callback cb;
gpointer cb_user_data;
static inm_dns_lookup_s *g_default_dns_lookup_data;
+static inline void __destroy_default_dns_lookup_data();
+
+static int __ares_set_opt(inm_dns_lookup_s *lookup_data)
+{
+ struct ares_options *p_opts = NULL;
+
+ p_opts = g_try_malloc0(sizeof(struct ares_options));
+ if (!p_opts) {
+ INM_LOGI("");
+ return -1;
+ }
+
+ p_opts->timeout = ARES_DEFAULT_TIMEOUT_MS;
+ p_opts->tries = ARES_DEFAULT_TRY;
+
+ lookup_data->ch_options = p_opts;
+
+ return 0;
+}
+
+static inline int __init_ares_channel(inm_dns_lookup_s *dns_lookup_data)
+{
+ ares_channel ch;
+ int opt_mask = 0;
+ int ret;
+
+ opt_mask = ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES | ARES_OPT_SOCK_STATE_CB;
+ ret = ares_init_options(&ch, dns_lookup_data->ch_options, opt_mask);
+ if (ret != ARES_SUCCESS) {
+ PRINT_LOG("ares_init_options: %s\n", ares_strerror(ret));
+ ares_destroy(ch);
+ return -1;
+ }
+
+ dns_lookup_data->channel = ch;
+
+ return 0;
+}
+
static inline int __create_default_dns_lookup_data()
{
inm_dns_lookup_s *dns_lookup_data = NULL;
+ int ret;
dns_lookup_data = g_try_malloc0(sizeof(inm_dns_lookup_s));
if (!dns_lookup_data) {
return -1;
}
+ ret = __ares_set_opt(dns_lookup_data);
+ if (ret != 0) {
+ INM_LOGI("");
+ g_free(dns_lookup_data);
+ return -1;
+ }
+ ret = __init_ares_channel(dns_lookup_data);
+ if (ret != 0) {
+ INM_LOGI("");
+ g_free(dns_lookup_data->ch_options);
+ g_free(dns_lookup_data);
+ return -1;
+ }
+
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;
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;
+ int err = INM_DNS_LOOKUP_ERROR_NONE;
+ gboolean result = TRUE;
+
+ __INM_FUNC_ENTER__;
+ if (!g_default_dns_lookup_data) {
+ __INM_FUNC_EXIT__;
+ return;
+ }
+
+ PRINT_LOG("status %s", ares_strerror(status));
+ dns_lookup_data = (inm_dns_lookup_s *)arg;
+ if (!p_host || status != ARES_SUCCESS) {
+ err = INM_DNS_LOOKUP_ERROR_OPERATION_FAILED;
+ result = FALSE;
+ }
+
+ dns_lookup_data->cb(err,
+ result,
+ p_host ? p_host->h_name : NULL,
+ dns_lookup_data->cb_user_data);
+
+ __INM_FUNC_EXIT__;
+}
+
static gboolean __default_dns_lookup_timer_cb(gpointer user_data)
{
inm_dns_lookup_s *dns_lookup_data;
__default_dns_lookup_timer_cb,
NULL);
+ ares_gethostbyname(g_default_dns_lookup_data->channel,
+ DEFAULT_TEST_URL,
+ AF_INET,
+ __ares_host_cb,
+ (void *)g_default_dns_lookup_data);
+
return 0;
}
int inm_dns_lookup_init()
{
+ int ret;
int version;
INM_LOGI("c-ares version %s", ares_version(&version));
+ ret = ares_library_init(ARES_LIB_INIT_ALL);
+ if (ret != ARES_SUCCESS) {
+ INM_LOGE("Lib init failed %s",
+ ares_strerror(ret));
+ return INM_DNS_LOOKUP_ERROR_OPERATION_FAILED;
+ }
return INM_DNS_LOOKUP_ERROR_NONE;
}