Index: /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_defs.h
===================================================================
--- /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_defs.h	(revision 20318)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_defs.h	(working copy)
@@ -261,6 +261,9 @@
 	uint8_t port_type;
 	uint16_t ports[RES_PORTS_MAX_NUM];
 	uint8_t res_type;
+
+	uint8_t is_hostname;
+	char hostname[128];
 } resource_t;
 
 typedef struct _vpn_commonconfig {
Index: /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c
===================================================================
--- /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c	(revision 20318)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c	(working copy)
@@ -368,8 +368,17 @@
 	/* search the resource host whether has existed */
 	res_network_queue_p = &(rqt->network_queue);
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
-		if ((res_network_p->ip_addr.ip4.sin_addr.s_addr & res_network_p->netmask.ip4.sin_addr.s_addr) == (res->ip.ip4 & res->mask.ip4))
+		if (res->is_hostname == 1 && (res_network_p->hostname != NULL && res->hostname != NULL))
 		{
+			if (strcmp(res_network_p->hostname, res->hostname) == 0)
+			{
+				res_network_p->is_hostname = res->is_hostname;
+				break;
+			}
+		}
+		else if ((res_network_p->ip_addr.ip4.sin_addr.s_addr & res_network_p->netmask.ip4.sin_addr.s_addr) == (res->ip.ip4 & res->mask.ip4))
+		{
+			res_network_p->is_hostname = 0;
 			break;
 		}
 	}
@@ -386,15 +395,28 @@
 		}
 		
 		TAILQ_INIT(&new_res_network_p->info_queue);
-		new_res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
-		new_res_network_p->ip_addr.ip4.sin_addr.s_addr = res->ip.ip4;
-		new_res_network_p->netmask.ip4.sin_len = sizeof(struct sockaddr_in);
-		new_res_network_p->netmask.ip4.sin_addr.s_addr = res->mask.ip4;
+		/* initialize ip of resource with hostname as 0 */
+		if (res->is_hostname == 1 && res->hostname != NULL) {
+			strncpy(new_res_network_p->hostname, res->hostname, 127);
+    			new_res_network_p->hostname[127] = '\0';
+			new_res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
+			new_res_network_p->ip_addr.ip4.sin_addr.s_addr = 0;
+			new_res_network_p->netmask.ip4.sin_len = sizeof(struct sockaddr_in);
+			new_res_network_p->netmask.ip4.sin_addr.s_addr = res->mask.ip4;
+			new_res_network_p->is_hostname = res->is_hostname;
+		}
+		else {
+			new_res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
+			new_res_network_p->ip_addr.ip4.sin_addr.s_addr = res->ip.ip4;
+			new_res_network_p->netmask.ip4.sin_len = sizeof(struct sockaddr_in);
+			new_res_network_p->netmask.ip4.sin_addr.s_addr = res->mask.ip4;
+			new_res_network_p->is_hostname = res->is_hostname;
+		}
 		
 		/* insert new resource host into the resource queue tree */
 		node = rqt->tree->rnh_addaddr((caddr_t)&new_res_network_p->ip_addr,
 						(caddr_t)&new_res_network_p->netmask, rqt->tree, new_res_network_p->nodes);
-		if (node != NULL) {
+		if (node != NULL || new_res_network_p->is_hostname == 1) {
 			TAILQ_INSERT_TAIL(res_network_queue_p, new_res_network_p, next_network);
 		} else {
 			free(new_res_network_p, M_VPN_NETWORK);
@@ -612,7 +634,14 @@
 	/* search the matched resource host */
 	res_network_queue_p = &rqt->network_queue;	
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
-		if (res_network_p->ip_addr.ip4.sin_addr.s_addr == res->ip.ip4 &&
+		if (res->is_hostname == 1 && (res_network_p->hostname != NULL && res->hostname != NULL))
+		{
+			if (strcmp(res_network_p->hostname, res->hostname) == 0)
+			{
+				break;
+			}
+		}
+		else if (res_network_p->ip_addr.ip4.sin_addr.s_addr == res->ip.ip4 &&
 			res_network_p->netmask.ip4.sin_addr.s_addr == res->mask.ip4)
 		{
 			break;
@@ -2237,6 +2266,7 @@
 
 	bzero(res, sizeof(*res));
 	res->protocol = RESOURCE_PROT_ALL;
+	res->is_hostname = 0;
 
 	if (!isdigit(*start)) {
 		if (strncasecmp(start, "udp://", sizeof("udp://") - 1) == 0) {
@@ -2249,8 +2279,18 @@
 			res->protocol = RESOURCE_PROT_ICMP;
 			start += sizeof("icmp://") - 1;
 		} else {
-			vpn_debug("resource %s have invalid resource type", start);
-			return -1;
+			/* resource configured with hostname */
+			strncpy(res->hostname, start, 127);
+            		res->hostname[127] = '\0';
+            		res->mask.ip4 = 0xFFFFFFFF;
+            		res->port_type = RESOURCE_PORTS_RANGE;
+            		res->ports[0] = 0;
+            		res->ports[1] = 65535;
+            		res->is_hostname = 1;
+
+            		return 0;
+			// vpn_debug("resource %s have invalid resource type", start);
+			// return -1;
 		}
 
 		if (*start == '\0') {
@@ -2448,6 +2488,7 @@
 
 	bzero(res, sizeof(*res));
 	res->protocol = RESOURCE_PROT_ALL;
+	res->is_hostname = 0;
 
 	/* parse protocol */
 	if (*start != '[') {
@@ -3394,8 +3435,15 @@
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
 		res_info_queue_p = &res_network_p->info_queue;
 		TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-			combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr, 
-				res_network_p->netmask.ip4.sin_addr.s_addr, res_info_p);
+            		if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+			{
+                		strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
+            		}
+            		else
+			{
+                		combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr,
+                    		res_network_p->netmask.ip4.sin_addr.s_addr, res_info_p);
+            		}
 			vpn_printf(CMD_VPN_RESOURCE_GROUPITEM_NETWORK, vrg->vr_groupname, buffer, 
 				res_info_p->res_type);
 		}
@@ -3421,8 +3469,15 @@
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
 		res_info_queue_p = &res_network_p->info_queue;
 		TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-			combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr, 
-				res_network_p->netmask.ip4.sin_addr.s_addr, res_info_p);
+			if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+			{
+                		strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
+            		}
+            		else
+			{
+                		combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr,
+                    		res_network_p->netmask.ip4.sin_addr.s_addr, res_info_p);
+            		}
 			vpn_printf(CMD_VPN_RESOURCE_GROUPEXCLUDEDITEM_NETWORK, vrg->vr_groupname, 
 				buffer, res_info_p->res_type);
 		}
@@ -3966,8 +4021,15 @@
 		TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
 			res_info_queue_p = &res_network_p->info_queue;
 			TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-				combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr, 
+				if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+				{
+					strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
+				}
+				else
+				{
+					combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr,
 					res_network_p->netmask.ip4.sin_addr.s_addr, res_info_p);
+				}
 				vpn_printf(CMD_VPN_RESOURCE_GROUPITEM_NETWORK, vrg->vr_groupname, buffer, 
 					res_info_p->res_type);
 			}
@@ -4320,8 +4382,15 @@
 		TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
 			res_info_queue_p = &res_network_p->info_queue;
 			TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-				combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr, 
+				if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+				{
+					strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
+				}
+				else
+				{
+					combine_network_resource(buffer, res_network_p->ip_addr.ip4.sin_addr.s_addr, 
 					res_network_p->netmask.ip4.sin_addr.s_addr, res_info_p);
+				}
 				vpn_printf(CMD_VPN_RESOURCE_GROUPEXCLUDEDITEM_NETWORK, vrg->vr_groupname, 
 					buffer, res_info_p->res_type);
 			}
Index: /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h
===================================================================
--- /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h	(revision 20318)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h	(working copy)
@@ -126,6 +126,9 @@
 		struct sockaddr_in6 ip6;
 	} netmask;
 
+	uint8_t is_hostname;
+	char hostname[128];
+
 	TAILQ_HEAD(resource_info_head, resource_info) info_queue;
 	TAILQ_ENTRY(resource_network) next_network;
 } resource_network_t;
Index: /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c
===================================================================
--- /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c	(revision 20318)
+++ /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c	(working copy)
@@ -41,6 +41,9 @@
 #include <click/app/fastlog/logex_def.h>
 #include <license.h>
 
+/* for dns resolve */
+#include <netdb.h>
+
 #define L3_PROTOCOL 0xFD
 #define MAX_DATA_SIZE 100
 
@@ -2604,6 +2607,59 @@
 	return 0;
 }
 
+static uint32_t 
+resolve_domain_to_ipv4(char domain[128]) 
+{
+	struct addrinfo hints, *res;
+	int status;
+	uint32_t ip_address = 0;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+
+	status = getaddrinfo(domain, NULL, &hints, &res);
+
+	if (status != 0) {
+		vpn_log_sendid("(%s): getaddrinfo failed, %s", __FUNCTION__, domain);
+		return 0;
+    	}
+
+    	struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr;
+    	ip_address = ipv4->sin_addr.s_addr;
+
+    	vpn_log_sendid("(%s): getaddrinfo %s -> %s", __FUNCTION__, domain, vpn_ntoa(ip_address));
+
+    	freeaddrinfo(res);
+
+    	return ip_address;
+}
+
+static void
+vpn_resource_resolve(struct resource_network_head *res_network_queue_p)
+{
+	resource_network_t *res_network_p;
+	uint32_t getdomainip;
+	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
+		if (res_network_p->is_hostname == 1 && (res_network_p->hostname != NULL))
+		{
+			getdomainip = resolve_domain_to_ipv4(res_network_p->hostname);
+			if (getdomainip != 0) 
+			{
+				res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
+				res_network_p->ip_addr.ip4.sin_addr.s_addr = getdomainip;
+				vpn_log_sendid("(%s): resolve_domain_to_ipv4 success: %s -> %s", __FUNCTION__, res_network_p->hostname, vpn_ntoa(getdomainip));
+			}
+			else {
+				res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
+				res_network_p->ip_addr.ip4.sin_addr.s_addr = inet_addr("1.1.1.1");
+				vpn_log_sendid("(%s): resolve_domain_to_ipv4 failed: %s", __FUNCTION__, res_network_p->hostname);
+			}
+	
+		}
+	}
+}
+
 vpn_action_t 
 vpn_tunnel_start(vpn_tunnel_t *vt) 
 {
@@ -2613,6 +2669,48 @@
 	vpn_tundata_t *vdate;
 	char buffer[1024];
 
+	/* resolve resource domain name to ip address while vpn tunnel starts */
+	struct resource_network_head *res_network_queue_p;
+	sec_role_t *role_p = NULL;
+	vpn_resourcegroup_t *vrg = NULL;
+	role_resource_t *res_p = NULL;
+	int i;
+	char netpools[SESSION_MAX_ROLE_PER_SESSION][VPN_NAME_MAX_LEN+1] = {{0}};
+	int netpool_num;
+	uint32_t getdomainip = 0;
+
+	vpn_log_sendid("(%s): find_vsite_by_name: %s", __FUNCTION__, vt->vt_vsite->name);
+
+	if (SEC_ISSET(vt->vt_secsession->flags, SESS_EXTERNAL_AUTH_INFO)) {
+		/*External netpools*/
+		netpool_num = netpool_names_to_array(vt->vt_secsession->vpn_netpools, netpools, SESSION_MAX_ROLE_PER_SESSION);
+		for (i = 0; i < netpool_num; i++) {
+			vrg = vpn_resourcegroup_lookup(vt->vt_vsite, netpools[i]);
+			if (vrg !=NULL) {
+				res_network_queue_p = &(vrg->network_list.network_queue);
+				vpn_resource_resolve(res_network_queue_p);
+				res_network_queue_p = &(vrg->excluded_network_list.network_queue);
+				vpn_resource_resolve(res_network_queue_p);
+			}
+		}
+	}
+	else {
+		for (i = 0; i < SESSION_MAX_ROLE_PER_SESSION; i++) {
+			role_p =  vt->vt_secsession->role_list[i];
+			if (NULL != role_p && !SLIST_EMPTY(&role_p->resource[ROLE_RES_VPNRESOURCEGROUP])) {
+				SLIST_FOREACH(res_p, &role_p->resource[ROLE_RES_VPNRESOURCEGROUP], next) {
+					vrg = vpn_resourcegroup_lookup(vt->vt_vsite, res_p->resource);
+					if (vrg != NULL) {
+						res_network_queue_p = &(vrg->network_list.network_queue);
+						vpn_resource_resolve(res_network_queue_p);
+						res_network_queue_p = &(vrg->excluded_network_list.network_queue);
+						vpn_resource_resolve(res_network_queue_p);
+					}
+				}
+			}
+		}
+	}
+
 	/*FUNCTION_ENTER(vt, NULL);
 	vpn_log_conn(vt->conn_p, "tunnel %p enter", vt);*/
 
