Index: /branches/rel_ag_9_4_5/aaa/aaa_localdb.c
===================================================================
--- /branches/rel_ag_9_4_5/aaa/aaa_localdb.c	(revision 20415)
+++ /branches/rel_ag_9_4_5/aaa/aaa_localdb.c	(working copy)
@@ -10,39 +10,90 @@
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <regex.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+#include <pthread.h>
+#include <unistd.h>
 
 #define MAX_IPS 10
 #define MAX_BUFFER_SIZE 8192
+#define MAX_DNS_SERVERS 3
 
 typedef struct {
     uint32_t ip_addresses[MAX_IPS];
     int count;
 } ip_list_t;
 
+typedef struct {
+    char *hostname;
+    char *dns_server;
+    ip_list_t *result;
+	int status;
+} dns_query_t;
+
+void *resolve(void *arg) {
+    	dns_query_t *query = (dns_query_t *)arg;
+	unsigned char response[1024];
+	ns_msg msg;
+    	ns_rr rr;
+    	int response_len, i;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+    	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+
+	res_init();
+	_res.nscount = 1;
+	_res.nsaddr_list[0].sin_family = AF_INET;
+    	_res.nsaddr_list[0].sin_addr.s_addr = inet_addr(query->dns_server);
+    	_res.nsaddr_list[0].sin_port = htons(53);
+
+	response_len = res_query(query->hostname, C_IN, T_A, response, sizeof(response));
+
+    	if (response_len < 0) {
+		query->status = -1;
+		aaa_debug_log("(%s): (%s) DNS query (%s) failed", __FUNCTION__, query->hostname, query->dns_server);
+        	return NULL;
+    	}
+
+	if (ns_initparse(response, response_len, &msg) < 0) {
+        	query->status = -1;
+        	return NULL;
+    	}
+
+    	query->result->count = 0;
+    	int ancount = ns_msg_count(msg, ns_s_an);
+    	for (i = 0; i < ancount && query->result->count < MAX_IPS; i++) {
+        	if (ns_parserr(&msg, ns_s_an, i, &rr) == 0 && ns_rr_type(rr) == ns_t_a) {
+            		struct in_addr ip_addr;
+            		memcpy(&ip_addr, ns_rr_rdata(rr), sizeof(ip_addr));
+            		query->result->ip_addresses[query->result->count++] = ip_addr.s_addr;
+        	}
+    	}
+    	query->status = 0;
+    	return NULL;
+}
+
 int is_ip_format(const char *domain) {
-    const char *pattern = "^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9.:-]+$";
-    regex_t regex;
-    int result;
-
-    if (regcomp(&regex, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
-        return 0;
-    }
+	const char *pattern = "^([0-9]{1,3}\\.){3}[0-9]{1,3}.+$";
+    	regex_t regex;
+	int result;
 
-    result = regexec(&regex, domain, 0, NULL, 0);
-    regfree(&regex);
+    	if (regcomp(&regex, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
+        	return 0;
+    	}
+
+    	result = regexec(&regex, domain, 0, NULL, 0);
+    	regfree(&regex);
     
-    return result == 0;
+    	return result == 0;
 }
 
 /* resolve domain name to ip address */
 static ip_list_t 
-*resolve_domain_to_ipv4(char domain[128]) 
-{
-	struct addrinfo hints, *res;
-	struct addrinfo *p;
-	int status;
-	ip_list_t *ip_list = malloc(sizeof(ip_list_t));
-	ip_list->count = 0;
+*resolve_domain_to_ipv4(char *domain) {
+    	char dns_servers[MAX_DNS_SERVERS][16];
+    	int dns_count = 0;
+	int i;
 
 	if (is_ip_format(domain))
 	{
@@ -50,25 +101,53 @@
 		return NULL;
 	}
 
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;
-	hints.ai_socktype = SOCK_STREAM;
+    	FILE *resolv = fopen("/etc/resolv.conf", "r");
+    	if (!resolv) {
+        	return NULL;
+    	}
 
-	status = getaddrinfo(domain, NULL, &hints, &res);
+    	char line[256];
+    	while (fgets(line, sizeof(line), resolv) && dns_count < MAX_DNS_SERVERS) {
+        	if (strncmp(line, "nameserver", 10) == 0 && dns_count < MAX_DNS_SERVERS) {
+            		sscanf(line, "nameserver %s", dns_servers[dns_count]);
+			dns_count++;
+        	}
+    	}
+    	fclose(resolv);
 
-	if (status != 0) 
-	{
-		aaa_error_log("(%s):resource resolve failed, %s", __FUNCTION__, domain);
+	ip_list_t *final_result = malloc(sizeof(ip_list_t));
+	if (!final_result) {
+		aaa_debug_log("(%s): Failed to allocate memory for final_result", __FUNCTION__);
 		return NULL;
 	}
-	for (p = res; p != NULL && ip_list->count < MAX_IPS; p = p->ai_next) {
-        	struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
-        	ip_list->ip_addresses[ip_list->count] = ipv4->sin_addr.s_addr;
-        	ip_list->count++;
-    	}
+    	final_result->count = 0;
 
-	freeaddrinfo(res);
-	return ip_list;
+    	pthread_t thread;
+    	dns_query_t query;
+
+	query.result = malloc(sizeof(ip_list_t));
+	query.result = final_result;
+	query.hostname = malloc(strlen(domain) + 1);
+    	strcpy(query.hostname, domain);
+
+    	for (i = 0; i < dns_count; i++) {
+		query.dns_server = malloc(strlen(dns_servers[i]) + 1);
+        	strcpy(query.dns_server, dns_servers[i]);
+		query.status = -1;
+		aaa_debug_log("(%s): hostname (%s) trying dns query via server (%s)", __FUNCTION__, query.hostname, query.dns_server);
+        	pthread_create(&thread, NULL, resolve, &query);
+		usleep(100000);
+		if (query.status != 0) {
+			aaa_debug_log("(%s): Timeout! Stopping DNS query", __FUNCTION__);
+			pthread_detach(thread);
+		}
+        	else if (query.status == 0 && final_result->count > 0) {
+			pthread_join(thread, NULL);
+            		return final_result;
+        	}
+    	}
+	free(final_result);
+    	return NULL;
 }
 
 int cli_sync(char* cli, char *vsite);
