Index: /branches/rel_apv_10_7_2/tools/update/ustacksystem.ks
===================================================================
--- /branches/rel_apv_10_7_2/tools/update/ustacksystem.ks	(revision 39193)
+++ /branches/rel_apv_10_7_2/tools/update/ustacksystem.ks	(working copy)
@@ -399,6 +399,8 @@
 oracle-instantclient-devel-21.5.0.0.0-1.x86_64
 unbound-libs-1.4.20-26.el7.x86_64
 ldns-1.6.16-7.el7.x86_64
+c-ares-1.33.1-2.el7.x86_64
+c-ares-devel-1.33.1-2.el7.x86_64
 %end
 
 %post --nochroot --interpreter ./tools/image-minimizer
Index: /branches/rel_apv_10_7_2/tools/ustackbuildenv.ks
===================================================================
--- /branches/rel_apv_10_7_2/tools/ustackbuildenv.ks	(revision 39193)
+++ /branches/rel_apv_10_7_2/tools/ustackbuildenv.ks	(working copy)
@@ -473,6 +473,8 @@
 libaio.x86_64
 oracle-instantclient-basic-21.5.0.0.0-1.x86_64
 oracle-instantclient-devel-21.5.0.0.0-1.x86_64
+c-ares-1.33.1-2.el7.x86_64
+c-ares-devel-1.33.1-2.el7.x86_64
 %end
 
 %post
Index: /branches/rel_apv_10_7_2/usr/click/lib/libdns_agent/Makefile
===================================================================
--- /branches/rel_apv_10_7_2/usr/click/lib/libdns_agent/Makefile	(revision 39193)
+++ /branches/rel_apv_10_7_2/usr/click/lib/libdns_agent/Makefile	(working copy)
@@ -34,7 +34,7 @@
 	  -L${.OBJDIR}/../libhttp_utils -lhttp_utils \
 	  -L${.OBJDIR}/../libfastlog -lfastlog \
 	  -L${.OBJDIR}/../libenglog -lenglog \
-	  -lcrypt -lanl -lm -lz
+	  -lcrypt -lanl -lcares -lm -lz
 
 .if defined(USTACK)
 .include <bsd.lib.mk>
Index: /branches/rel_apv_10_7_2/usr/click/lib/libdns_agent/dns_daemon.c
===================================================================
--- /branches/rel_apv_10_7_2/usr/click/lib/libdns_agent/dns_daemon.c	(revision 39193)
+++ /branches/rel_apv_10_7_2/usr/click/lib/libdns_agent/dns_daemon.c	(working copy)
@@ -25,6 +25,7 @@
 #include "amp_ulog.h"
 #include <fastlog.h>
 #include <click/app/proxy/proxy_lib_hash.h>
+#include <ares.h>
 
 #define NAMESERVER_UPDATE_INTERVAL 30 /* second */
 #define DNS_AGENT_SLEEP_TIME    1000  /* microsecond */
@@ -50,9 +51,16 @@
 	webagent_dns_data_t *webagent_ctx;
 	struct gaicb *req[1];
 	struct gaicb req_item;
+	uint32_t ttl;
 };
+
+typedef struct {
+    uint32_t *ttl;
+    volatile int *done;
+} dns_cb_ctx_t;
+
 #define DNS_REQ_LIST_LEN 20
-#define DEFAULT_WEBAGENT_DNS_TTL 1 
+#define DEFAULT_WEBAGENT_DNS_TTL 1
 
 static __thread struct dns_req_ctx dns_req_wait_list[DNS_REQ_LIST_LEN];
 __thread int outstanding_dns_req_cnt = 0;
@@ -414,11 +422,42 @@
 	return;
 }
 
+/* c-ares ares_getaddrinfo() callback function */
+static void
+addrinfo_cb(void *arg, int status, int timeouts, struct ares_addrinfo *result)
+{
+	dns_cb_ctx_t *ctx = (dns_cb_ctx_t *)arg;
+	uint32_t *ttl = ctx->ttl;
+	volatile int *done = ctx->done;
+
+	// fastlog_syslog(LOG_DEBUG,"%s: Result: %d(%s), timeouts: %d", __FUNCTION__, status, ares_strerror(status), timeouts);
+	fastlog_syslog(LOG_DEBUG,"%s: rv: %d, t: %d", __FUNCTION__, status, timeouts);
+	if (result) {
+		struct ares_addrinfo_node *node = result->nodes;
+		*ttl = node->ai_ttl;
+	}
+	else{
+		// fastlog_syslog(LOG_DEBUG, "%s: no result from ares_getaddrinfo()", __FUNCTION__);
+	}
+	ares_freeaddrinfo(result);
+	*done = 1;
+}
+
 static int
 domain_resolve_asynch(char *host, webagent_dns_data_t *dns_data_p)
 {
 	int free_idx = 0;
 	int ret;
+	ares_channel_t *channel = NULL;
+	struct ares_options options;
+	int	optmask = 0;
+	struct ares_addrinfo_hints hints;
+	uint32_t ttl = 0;
+	volatile int done = 0;
+	dns_cb_ctx_t ctx = {
+		.ttl = &ttl,
+		.done = &done,
+	};
 
 	/* find first free slot and Queue nreqs_base..nreqs requests. */
 	while (free_idx < DNS_REQ_LIST_LEN) {
@@ -448,6 +487,43 @@
 	/* dns req successfully sent */
 	dns_req_wait_list[free_idx].webagent_ctx = dns_data_p;
 	dns_req_wait_list[free_idx].busy_fl = 1;
+
+	/* libcares method to get ttl and assign to dns_req_wait_list[].ttl */
+	ares_library_init(ARES_LIB_INIT_ALL);
+
+	memset(&options, 0, sizeof(options));
+	optmask = ARES_OPT_EVENT_THREAD | ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES | ARES_OPT_SERVER_FAILOVER;
+	options.evsys = ARES_EVSYS_DEFAULT;
+	options.timeout = 250;  // ms
+	options.tries = 1;      // per nameserver
+
+	if (ares_init_options(&channel, &options, optmask) != ARES_SUCCESS) {
+		fastlog_syslog(LOG_DEBUG, "c-ares initialization issue");
+		dns_req_wait_list[free_idx].ttl = 0; /* will assign DEFAULT_WEBAGENT_DNS_TTL in domain_resolve_poll() */
+	} else {
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = AF_UNSPEC;
+		hints.ai_flags  = ARES_AI_CANONNAME;
+		ares_getaddrinfo(channel, host, NULL, &hints, addrinfo_cb, &ctx);
+
+		int total_waited = 0;
+		while (!done && total_waited < 500) { // at most 0.5 sec
+			usleep(DNS_AGENT_SLEEP_TIME);     // 0.001 sec
+			total_waited += 1;
+		}
+		fastlog_syslog(LOG_DEBUG, "handle: %d", total_waited);
+
+		if (!done)
+		{
+			fastlog_syslog(LOG_DEBUG, "%s callback timed out", host);
+		}
+
+		ares_destroy(channel);
+		dns_req_wait_list[free_idx].ttl = ttl;
+	}
+	ares_library_cleanup();
+
+
 	outstanding_dns_req_cnt++;
 	//fastlog_syslog(LOG_DEBUG, "%s: sent req for %s(idx %d), out reqs %d",
 	//	       __FUNCTION__, host, free_idx, outstanding_dns_req_cnt);
@@ -459,6 +535,7 @@
 {
 	poll_item->webagent_ctx = NULL;
 	poll_item->busy_fl = 0;
+	poll_item->ttl = 0;
 	outstanding_dns_req_cnt--;
 }
 
@@ -489,15 +566,22 @@
 			if (res->ai_addr->sa_family == AF_INET) {
 				struct sockaddr_in *my_addr = (struct sockaddr_in *)res->ai_addr;
 				fastlog_syslog(LOG_DEBUG, "%s: [%d], outstanding req %d, thread id %d: host %s -> ip %s",
-					       __FUNCTION__, i, outstanding_dns_req_cnt, webagent_ctx->thread_id,
-					       webagent_ctx->host, inet_ntoa(my_addr->sin_addr));
-
+							__FUNCTION__, i, outstanding_dns_req_cnt, webagent_ctx->thread_id,
+							webagent_ctx->host, inet_ntoa(my_addr->sin_addr));
 				webagent_ctx->iptable.ip4_dns_record_table[0].ip = my_addr->sin_addr.s_addr;
-                                webagent_ctx->iptable.ip4_dns_record_table[0].ttl = DEFAULT_WEBAGENT_DNS_TTL;
+				if (dns_req_wait_list[i].ttl){		/* check if ttl is valid */
+					webagent_ctx->iptable.ip4_dns_record_table[0].ttl = dns_req_wait_list[i].ttl;
+				}else{
+					webagent_ctx->iptable.ip4_dns_record_table[0].ttl = DEFAULT_WEBAGENT_DNS_TTL;
+				}
 			} else {
 				struct sockaddr_in6 *my_addr = (struct sockaddr_in6 *)res->ai_addr;
 				webagent_ctx->iptable.ip6_dns_record_table[0].ip = my_addr->sin6_addr;
-                                webagent_ctx->iptable.ip6_dns_record_table[0].ttl = DEFAULT_WEBAGENT_DNS_TTL;
+				if (dns_req_wait_list[i].ttl){
+					webagent_ctx->iptable.ip6_dns_record_table[0].ttl = dns_req_wait_list[i].ttl;
+				}else{
+					webagent_ctx->iptable.ip6_dns_record_table[0].ttl = DEFAULT_WEBAGENT_DNS_TTL;
+				}
 			}
 			webagent_ctx->ip_num = 1;
 		} else {
Index: /branches/rel_apv_10_7_2/usr/click/lib/libuinet-atcp/bin/atcp/Makefile
===================================================================
--- /branches/rel_apv_10_7_2/usr/click/lib/libuinet-atcp/bin/atcp/Makefile	(revision 39193)
+++ /branches/rel_apv_10_7_2/usr/click/lib/libuinet-atcp/bin/atcp/Makefile	(working copy)
@@ -11,7 +11,7 @@
 CXXFLAGS= -std=c++11 -I${TOPDIR}/../libbreakpad/build/src
 LIBBREAKPAD_CLIENT=${TOPDIR}/../libbreakpad/build/src/client/linux/libbreakpad_client.a
 ifneq ($(ARM64), yes)
-LDADD= -L${UINET_DESTDIR}/lib/ -lanl -lm -lpcap \
+LDADD= -L${UINET_DESTDIR}/lib/ -lanl -lcares -lm -lpcap \
 	-L${RTE_SDK}/${RTE_TARGET}/lib -ldpdk \
 	-Wl,--start-group \
 	-L${TOPDIR}/../libenv -lenv \
