From 20f8439bd295bba52247c19f86db9bf574dcee4b Mon Sep 17 00:00:00 2001 From: "qi1988.yang" Date: Tue, 17 Nov 2015 17:02:41 +0800 Subject: [PATCH] Maintain a DNS cache in soup library to reduce DNS request time [Problem] Prefetch DNS need supporting of DNS Cache [Cause] Support DNS Cache in libsoup [Solution] Maintain a DNS cache in soup library to reduce DNS request time. Change-Id: Ic4d580cda32baaba97bf285c4286f4543000bcba Signed-off-by: qi1988.yang --- configure.ac | 16 ++++++ libsoup/soup-address.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++-- packaging/libsoup.spec | 1 + 3 files changed, 145 insertions(+), 3 deletions(-) mode change 100755 => 100644 configure.ac mode change 100755 => 100644 packaging/libsoup.spec diff --git a/configure.ac b/configure.ac old mode 100755 new mode 100644 index 125c0d7..1520c23 --- a/configure.ac +++ b/configure.ac @@ -370,6 +370,22 @@ AC_MSG_RESULT($enable_tizen_disable_mime_sniff) AM_CONDITIONAL(TIZEN_TV_DISABLE_MIME_SNIFF, [test $enable_tizen_disable_mime_sniff = yes]) +dnl **************************** +dnl *** Tizen soup store dns *** +dnl **************************** + +AC_ARG_ENABLE(tizen-soup-store-dns, + AS_HELP_STRING([--enable-tizen-soup-store-dns], [Enable Tizen soup store dns ]), , + enable_tizen_soup_store_dns=no) + +AC_MSG_CHECKING([for Tizen soup store dns]) +if test $enable_tizen_soup_store_dns != no;then + AC_DEFINE(ENABLE_TIZEN_TV_SOUP_STORE_DNS, 1, [Maintain a DNS cache in soup library to reduce DNS request time]) +fi +AC_MSG_RESULT($enable_tizen_soup_store_dns) + +AM_CONDITIONAL(TIZEN_TV_SOUP_STORE_DNS, [test $enable_tizen_soup_store_dns = yes]) + dnl *********************************************** dnl *** Tizen support soup immediate requesting *** dnl *********************************************** diff --git a/libsoup/soup-address.c b/libsoup/soup-address.c index b2d1647..4479f7b 100644 --- a/libsoup/soup-address.c +++ b/libsoup/soup-address.c @@ -16,6 +16,14 @@ #include "soup-address.h" #include "soup.h" #include "soup-misc-private.h" +#include "TIZEN.h" + +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) +#include +#include +#include "soup-session.h" +#include "glib.h" +#endif /** * SECTION:soup-address @@ -53,6 +61,16 @@ typedef struct { GMutex lock; } SoupAddressPrivate; + +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) +typedef struct { + gchar *key; + gchar *ip; + time_t time; + guint port; +} IPAndPort; +#endif + #define SOUP_ADDRESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_ADDRESS, SoupAddressPrivate)) /* sockaddr generic macros */ @@ -94,6 +112,14 @@ typedef struct { #define SOUP_ADDRESS_SET_DATA(priv, data, length) \ memcpy (SOUP_ADDRESS_GET_DATA (priv), data, length) +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) +#define DNS_CACHE_HASHTABLE_MAX_COUNT 30 +#define DNS_CACHE_MAX_TIME_SECOND 60 +static GHashTable *dns_cache = NULL; +static GList *hostkey = NULL; +static IPAndPort* ipandport_cache_new (gchar *key, gchar *ip, time_t time, guint port); +static void ipandport_cache_free (IPAndPort* ipandport); +#endif static void soup_address_connectable_iface_init (GSocketConnectableIface *connectable_iface); @@ -621,6 +647,16 @@ update_addrs (SoupAddress *addr, GList *addrs, GError *error) GSocketAddress *gsa; int i; +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) + IPAndPort *ipandport = NULL; + IPAndPort *oldipandport = NULL; + IPAndPort *deloldipandport = NULL; + gchar *tempIPaddress = NULL; + time_t timep; + int hashtablecount = 0; + GList *templist = NULL; +#endif + if (error) { if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) @@ -636,6 +672,40 @@ update_addrs (SoupAddress *addr, GList *addrs, GError *error) priv->sockaddr = g_new (struct sockaddr_storage, priv->n_addrs); for (i = 0; addrs; addrs = addrs->next, i++) { gia = addrs->data; +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) + if ((0 == i) && (!addrs->next) && (dns_cache)) { + tempIPaddress = g_inet_address_to_string (gia); + oldipandport = g_hash_table_lookup (dns_cache, priv->name); + if (oldipandport) { + time (&timep); + hostkey = g_list_remove (hostkey, oldipandport->key); + oldipandport->time = timep; + hostkey = g_list_append (hostkey, oldipandport->key); + } else { + hashtablecount = g_hash_table_size (dns_cache); + if (hashtablecount < DNS_CACHE_HASHTABLE_MAX_COUNT) { + time (&timep); + ipandport = ipandport_cache_new (priv->name, tempIPaddress, timep, priv->port ); + g_hash_table_insert (dns_cache, ipandport->key, ipandport); + hostkey = g_list_append (hostkey, ipandport->key); + } else { + templist = g_list_first (hostkey); + if (templist) { + deloldipandport = g_hash_table_lookup (dns_cache, templist->data); + if (deloldipandport) { + time (&timep); + hostkey = g_list_remove (hostkey, deloldipandport->key); + g_hash_table_remove (dns_cache, deloldipandport->key); + ipandport_cache_free (deloldipandport); + ipandport = ipandport_cache_new (priv->name, tempIPaddress, timep, priv->port); + g_hash_table_insert (dns_cache, ipandport->key, ipandport); + hostkey = g_list_append (hostkey, ipandport->key); + } + } + } + } + } +#endif gsa = g_inet_socket_address_new (gia, priv->port); if (!g_socket_address_to_native (gsa, &priv->sockaddr[i], @@ -754,6 +824,30 @@ idle_complete_resolve (gpointer res_data) return FALSE; } +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) +static IPAndPort* ipandport_cache_new (gchar *key, gchar *ip, time_t time, guint port) +{ + IPAndPort *ipandport; + ipandport = g_new (IPAndPort, 1); + ipandport->key = g_strdup (key); + ipandport->ip = g_strdup (ip); + ipandport->time = time; + ipandport->port = port; + return ipandport; +} + +static void ipandport_cache_free (IPAndPort* ipandport) +{ + g_return_if_fail (ipandport != NULL); + g_free (ipandport->key); + g_free (ipandport->ip); + g_free (ipandport); + ipandport->key = NULL; + ipandport->ip = NULL; + ipandport = NULL; +} +#endif + /** * SoupAddressCallback: * @addr: the #SoupAddress that was resolved @@ -797,6 +891,13 @@ soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context, SoupAddressResolveAsyncData *res_data; GResolver *resolver; +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) + IPAndPort *ipandport = NULL; + time_t timep; + GList *addrs; + guint status; +#endif + g_return_if_fail (SOUP_IS_ADDRESS (addr)); priv = SOUP_ADDRESS_GET_PRIVATE (addr); g_return_if_fail (priv->name || priv->sockaddr); @@ -823,10 +924,34 @@ soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context, else { resolver = g_resolver_get_default (); +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) + if (!dns_cache) + dns_cache = g_hash_table_new (g_str_hash, g_str_equal); +#endif + if (priv->name) { - g_resolver_lookup_by_name_async (resolver, priv->name, - cancellable, - lookup_resolved, res_data); +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) + if (dns_cache) + ipandport = g_hash_table_lookup (dns_cache, priv->name); + if (ipandport) { + time (&timep); + if((timep - ipandport->time) <= DNS_CACHE_MAX_TIME_SECOND){ + addrs = g_resolver_lookup_by_name (resolver, ipandport->ip, cancellable, NULL); + status = update_addrs (res_data->addr, addrs, NULL); + complete_resolve_async (res_data, status); + } else { + g_resolver_lookup_by_name_async (resolver, priv->name, + cancellable, + lookup_resolved, res_data); + } + } else { +#endif + g_resolver_lookup_by_name_async (resolver, priv->name, + cancellable, + lookup_resolved, res_data); +#if ENABLE(TIZEN_TV_SOUP_STORE_DNS) + } +#endif } else { GInetAddress *gia; diff --git a/packaging/libsoup.spec b/packaging/libsoup.spec old mode 100755 new mode 100644 index 5c077c8..12c3672 --- a/packaging/libsoup.spec +++ b/packaging/libsoup.spec @@ -106,6 +106,7 @@ chmod +x autogen.sh --enable-tizen-tv-force-preload-tlsdb \ --enable-tizen-tv-no-cache-about-video-and-audio \ --enable-tizen-performance-test-log \ + --enable-tizen-soup-store-dns \ %endif --disable-static make %{?_smp_mflags} -- 2.7.4