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 20482)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c	(working copy)
@@ -3877,12 +3877,14 @@
 	res.res_type = type;
 
 	vrg = vpn_resourcegroup_lookup(vsite, name);
+	vrg->limit = 0;
 	if (vrg == NULL) {
 		vpn_fail(FAIL_VPN_RESOURCEGROUP_NOT_EXIST, FAIL_VPN_RESOURCEGROUP_NOT_EXIST_INFO, name);
 		return -1;
 	}
 
 	if (get_resourcegroup_network_num(vrg) >= g_vpn_network_limit) {
+		vrg->limit = 1;
 		vpn_fail(FAIL_VPN_RESOURCE_ITEM_NETWORK_NETWORK_REACH_LIMIT, 
 			FAIL_VPN_RESOURCE_ITEM_NETWORK_NETWORK_REACH_LIMIT_INFO, 
 			g_vpn_network_limit);
@@ -4248,12 +4250,14 @@
 	res.res_type = type;
 	
 	vrg = vpn_resourcegroup_lookup(vsite, name);
+	vrg->limit = 0;
 	if (vrg == NULL) {
 		vpn_fail(FAIL_VPN_RESOURCEGROUP_NOT_EXIST, FAIL_VPN_RESOURCEGROUP_NOT_EXIST_INFO, name);
 		return -1;
 	}
 
 	if (get_resourcegroup_excludednetwork_num(vrg) >= g_vpn_network_limit) {
+		vrg->limit = 1;
 		vpn_fail(FAIL_VPN_RESOURCE_ITEM_NETWORK_NETWORK_REACH_LIMIT, 
 			FAIL_VPN_RESOURCE_ITEM_NETWORK_NETWORK_REACH_LIMIT_INFO, 
 			g_vpn_network_limit);
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 20482)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h	(working copy)
@@ -162,6 +162,7 @@
 	resource_queue_tree_t excluded_network6_list;
 	struct _vpn_vsite *vr_vvs;
 	TAILQ_ENTRY(_vpn_resourcegroup) next_resourcegroup;
+	uint8_t limit;
 } vpn_resourcegroup_t;
 
 #define VPN_PEER_LOCAL	1
Index: /branches/rel_ag_9_4_5/aaa/aaa_localdb.c
===================================================================
--- /branches/rel_ag_9_4_5/aaa/aaa_localdb.c	(revision 20482)
+++ /branches/rel_ag_9_4_5/aaa/aaa_localdb.c	(working copy)
@@ -966,29 +966,82 @@
 	return;
 }
 
+#define MAX_KNOWN_IPS 1024
+#define MAX_KNOWN_DOMAINS 512
+#define MAX_DOMAIN_LENGTH 256
+
+static char *known_ips[MAX_KNOWN_IPS];
+static int known_ip_count = 0;
+char known_domains[MAX_KNOWN_DOMAINS][MAX_DOMAIN_LENGTH];
+char domain_groups[MAX_KNOWN_DOMAINS][MAX_DOMAIN_LENGTH];
+static int known_domain_count = 0;
+
+void init_known_lists()
+{
+    known_ip_count = 0;
+    known_domain_count = 0;
+}
+
+void extract_ip(const char *input, char *output, size_t size) {
+    const char *end = input;
+    size_t len = 0;
+
+    while (*end && *end != '/' && *end != ':') {
+        end++;
+    }
+
+    len = end - input;
+    if (len >= size)
+        len = size - 1;
+
+    strncpy(output, input, len);
+    output[len] = '\0';
+}
+
+int ip_in_known_list(const char *ip) {
+    char pure_ip[64];
+    char known_pure_ip[64];
+    int i;
+
+    extract_ip(ip, pure_ip, sizeof(pure_ip));
+
+    for (i = 0; i < known_ip_count; i++) {
+        extract_ip(known_ips[i], known_pure_ip, sizeof(known_pure_ip));
+        if (strcmp(pure_ip, known_pure_ip) == 0) {return 1;}
+    }
+
+    return 0;
+}
+
+void add_ip_to_known_list(const char *ip) {
+    if (known_ip_count >= MAX_KNOWN_IPS)
+        return;
+    known_ips[known_ip_count++] = strdup(ip);
+}
+
 void 
 run_add_vpnres(char *show_resource, char *vsite, int is_exclude)
 {
 	/* split the output to get vpn group name and resource */
 	char *content_start = strstr(show_resource, "\"content\":");
-    	if (!content_start) {
+	if (!content_start) {
 		aaa_error_log("(%s): Error: 'content' not found", __FUNCTION__);
 		return;
-    	}
+	}
 
 	content_start = strchr(content_start, '[');
-    	if (!content_start) {
+	if (!content_start) {
 		aaa_error_log("(%s): Error: '[' not found", __FUNCTION__);
 		return;
-    	}
+	}
 
-    	char *current = content_start + 1;
+	char *current = content_start + 1;
 	/* get resourcegroup */
-    	while ((current = strstr(current, "\"resourcegroup\":")) != NULL) {
-        	char group_name[256] = {0};
-        	char netresource[256] = {0};
+	while ((current = strstr(current, "\"resourcegroup\":")) != NULL) {
+		char group_name[256] = {0};
+		char netresource[256] = {0};
 
-        	char *group_start = strchr(current, ':');
+		char *group_start = strchr(current, ':');
 		if (group_start) {
 			group_start = strchr(group_start, '\"');
 			if (group_start) {
@@ -1002,7 +1055,7 @@
 		aaa_debug_log("(%s): group_name \"%s\"", __FUNCTION__, group_name);
 
 		/* get network resource */
-        	current = strstr(current, "\"netresource\":");
+		current = strstr(current, "\"netresource\":");
 		if (!current) {
 			break;
 		}
@@ -1019,32 +1072,57 @@
 				}
 			}
 		}
+
 		aaa_debug_log("(%s): netresource \"%s\"", __FUNCTION__, netresource);
-		/* resolve the resource and add it into vpn group */
-		char cli[MAX_LINE_SIZE + 1];
-		ip_list_t *ips;
-		struct in_addr addr;
-		int i;
-		ips = resolve_domain_to_ipv4(netresource);
-		if (ips != NULL)
-		{
-			for (i = 0; i < ips->count; i++) {
-				addr.s_addr = ips->ip_addresses[i];
-				if (!is_exclude)
-				{
-					snprintf(cli, sizeof(cli), "/ca/bin/backend -s \"%s\" -C \"vpn resource groupitem network \"%s\" %s/32\"", vsite, group_name, inet_ntoa(addr));
-					system(cli);
-					aaa_debug_log("(%s): use system command: %s", __FUNCTION__, cli);
-				}
-				else {
-					snprintf(cli, sizeof(cli), "/ca/bin/backend -s \"%s\" -C \"vpn resource groupexcludeditem network \"%s\" %s/32\"", vsite, group_name, inet_ntoa(addr));
-					system(cli);
-					aaa_debug_log("(%s): use system command: %s", __FUNCTION__, cli);
+		if (is_ip_format(netresource)) {
+			aaa_debug_log("(%s): resource is ip %s", __FUNCTION__, netresource);
+			if (!ip_in_known_list(netresource)) {
+				add_ip_to_known_list(netresource);
+				aaa_debug_log("(%s): add to ip list (%s)", __FUNCTION__, netresource);
+			}
+		}
+		else {
+			/* resource is domain */
+			aaa_debug_log("(%s): resource is not ip %s", __FUNCTION__, netresource);
+			if (known_domain_count < MAX_DOMAIN_LENGTH) {
+				strncpy(known_domains[known_domain_count], netresource, 256);
+				strncpy(domain_groups[known_domain_count], group_name, 256);
+				known_domain_count++;
+			}
+		}
+		current = net_end ? net_end + 1 : current + 1;
+		}
+
+		int d, i;
+		for (d = 0; d < known_domain_count; d++) {
+			ip_list_t *ips = resolve_domain_to_ipv4(known_domains[d]);
+			if (ips != NULL) {
+				for (i = 0; i < ips->count; i++) {
+					struct in_addr addr;
+					addr.s_addr = ips->ip_addresses[i];
+					char *ip_str = inet_ntoa(addr);
+
+					if (!ip_in_known_list(ip_str)) {
+						char cli[MAX_LINE_SIZE + 1];
+						if (!is_exclude) {
+							snprintf(cli, sizeof(cli),
+								"/ca/bin/backend -s \"%s\" -C \"vpn resource groupitem network \\\"%s\\\" %s/32\"",
+								vsite, domain_groups[d], ip_str);
+						} else {
+							snprintf(cli, sizeof(cli),
+								"/ca/bin/backend -s \"%s\" -C \"vpn resource groupexcludeditem network \\\"%s\\\" %s/32\"",
+								vsite, domain_groups[d], ip_str);
+						}
+
+						system(cli);
+						aaa_debug_log("(%s): add domain ip: %s", __FUNCTION__, ip_str);
+						aaa_debug_log("(%s): use system command: %s", __FUNCTION__, cli);
+						add_ip_to_known_list(ip_str);
+					}
 				}
+				free(ips);
 			}
 		}
-		 current = net_end ? net_end + 1 : current + 1;
-    	}
 }
 
 void 
@@ -1063,22 +1141,23 @@
 	}
 
 	while (fgets(show_vpnres_output + bytes_read, MAX_BUFFER_SIZE - bytes_read, fp) != NULL) {
-        	bytes_read += strlen(show_vpnres_output + bytes_read);
-        	if (bytes_read >= MAX_BUFFER_SIZE - 1) {
+		bytes_read += strlen(show_vpnres_output + bytes_read);
+		if (bytes_read >= MAX_BUFFER_SIZE - 1) {
 			break;
 		}
-    	}
+	}
 	aaa_debug_log("(%s): %s \"%s\"", __FUNCTION__, cmd, show_vpnres_output);
 
 	/* add vpn resource with the output */
+	init_known_lists();
 	run_add_vpnres(show_vpnres_output, vsite, is_exclude);
 
-    	pclose(fp);
+	pclose(fp);
 }
 
 int32_t
-ldb_authorize_hardwareid(struct request_handle *qh, char *vsite, char *username, char *groupname, 
-                                  char *orig_hardwareid, hardwareid_pending_list_t *pending_list)
+ldb_authorize_hardwareid(struct request_handle *qh, char *vsite, char *username, char *groupname,
+							char *orig_hardwareid, hardwareid_pending_list_t *pending_list)
 {
 	uint32_t group_flags;
 	int ret, aggregation;
Index: /branches/rel_ag_9_4_5/uproxy/http_proxy/smanager/sec_misc.c
===================================================================
--- /branches/rel_ag_9_4_5/uproxy/http_proxy/smanager/sec_misc.c	(revision 20482)
+++ /branches/rel_ag_9_4_5/uproxy/http_proxy/smanager/sec_misc.c	(working copy)
@@ -185,6 +185,7 @@
 array_des3_encrypt(uint8_t *key, uint32_t key_len, uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len);
 static int32_t issue_hwid_regist_request(void *client_conn_p, char *vsite_name, char *verify_code);
 static int issue_hwid_device_list(smanager_data_t *sec_data);
+extern vpn_resourcegroup_t *vpn_resourcegroup_lookup(char *vsite, char *name);
 
 static char portal_temp_string[MAX_APP_PRINT_SIZE];
 static char portal_lang_buffer[MAX_APP_PRINT_SIZE];
@@ -5236,6 +5237,20 @@
 
 	write_data(str, cursor, strlen(str), out_frame);
 
+	/* check if vpn resource number reaches limit */
+	if (vsite->vvs != NULL) {
+		vpn_resourcegroup_t *vrg;
+		TAILQ_FOREACH(vrg, &vsite->vvs->vpn_resource_q, next_resourcegroup) {
+			if (vrg->limit == 1) {
+				snprintf(str, 1024, "var _AN_res_limit_check_%s = 1;\n", vrg->vr_groupname);
+			}
+			else {
+				snprintf(str, 1024, "var _AN_res_limit_check_%s = 0;\n", vrg->vr_groupname);
+			}
+			write_data(str, cursor, strlen(str), out_frame);
+		}
+	}
+
 	/* change password */
 	if( vsite->aaa_configure == NULL || vsite->aaa_configure->aaa_on == AAA_IS_OFF || sec_session->method_id[0] == '\0' ) {
 		lang_string = "";
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 20482)
+++ /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c	(working copy)
@@ -3597,7 +3597,7 @@
 		res_info_queue_p = &res_network_p->info_queue;
 
 		if (!is_ipv6 && res_network_p->ip_addr.ip4.sin_addr.s_addr == inet_addr("127.0.0.1")) {
-			if(res_network_p->hostname != NULL)
+			if(res_network_p->hostname[0] != '\0')
 			{
 				vpn_log_connect("(%s): skip invalid resource %s", __FUNCTION__, res_network_p->hostname);
 			}
