summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhangchengwei <[email protected]>2018-11-19 17:18:25 +0800
committerzhangchengwei <[email protected]>2018-11-19 17:18:25 +0800
commit4c2dc7aed349cd34f582ae35d261e92619b62737 (patch)
tree935331181d6d9d6be3fcc8989058e199ff2e4d3f
创建
-rw-r--r--bin/conf/maat_cfg1/full/2018-06-16/APP_DOMAIN.00000000013
-rw-r--r--bin/conf/maat_cfg1/full/2018-06-16/APP_POLICY.00000000013
-rw-r--r--bin/conf/maat_cfg1/full/2018-07-10/LIMIT_DOMAIN.00000000012
-rw-r--r--bin/conf/maat_cfg1/full/full_config_index.00000000019
-rw-r--r--bin/conf/maat_cfg1/full/full_config_index.0000000001_real9
-rw-r--r--bin/conf/maat_cfg1/full/index/full_config_index.00000000019
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.00000000023
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.00000000042
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.00000000052
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.00000000072
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.00000000082
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.00000000092
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.00000000033
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.00000000042
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.00000000062
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.00000000072
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.00000000082
-rw-r--r--bin/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.00000000013
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000029
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.0000000002_bak9
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.0000000002_real9
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000039
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.0000000003_bak9
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000049
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000059
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000069
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000079
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000089
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000099
-rw-r--r--bin/conf/maat_cfg1/inc/inc_config_index.00000000109
-rw-r--r--bin/conf/maat_cfg2/full/2018-06-16/APP_DYN_SEV_IP_CB.00000000013
-rw-r--r--bin/conf/maat_cfg2/full/full_config_index.00000000019
-rw-r--r--bin/conf/maat_cfg2/full/index/full_config_index.00000000019
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000023
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000032
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000042
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000052
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000062
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000072
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.000000000811
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000096
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000106
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000116
-rw-r--r--bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.00000000202
-rw-r--r--bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.00000000012
-rw-r--r--bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.00000000022
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.00000000029
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000002_bak9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000002_real9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000002_xxxxx9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.00000000039
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000003_bak9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000003_real9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.00000000049
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000004_bak9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.00000000059
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000005_bak9
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.00000000069
-rw-r--r--bin/conf/maat_cfg2/inc/inc_config_index.0000000006_bak9
-rw-r--r--bin/conf/maat_table_info.conf24
-rw-r--r--bin/conf/pangu_valve.conf30
-rw-r--r--bin/conf/table_info/maat_info.conf6
-rw-r--r--bin/conf/table_info/service_id_map.conf40
-rw-r--r--bin/conf/table_info/service_id_map_test.conf67
-rw-r--r--bin/conf/table_info/table_info_one.conf10
-rw-r--r--bin/conf/table_info/table_info_tree.conf6
-rw-r--r--bin/firstconnect.txt0
-rw-r--r--bin/memchk.sh2
-rw-r--r--bin/pangu_valvebin0 -> 602530 bytes
-rw-r--r--bin/pangu_valve_dmn.sh25
-rw-r--r--bin/pangu_valve_start.sh3
-rw-r--r--bin/pangu_valve_stop.sh2
-rw-r--r--bin/pangu_valve_testbin0 -> 606097 bytes
-rw-r--r--src/Makefile41
-rw-r--r--src/cJSON/cJSON.c596
-rw-r--r--src/cJSON/cJSON.h143
-rw-r--r--src/check_ip_legal.c241
-rw-r--r--src/check_ip_legal.h33
-rw-r--r--src/include/MESA/MESA_handle_logger.h68
-rw-r--r--src/include/MESA/MESA_htable.h378
-rw-r--r--src/include/MESA/MESA_list_queue.h115
-rw-r--r--src/include/MESA/MESA_prof_load.h179
-rw-r--r--src/include/MESA/Maat_rule.h239
-rw-r--r--src/include/MESA/asmis_log.h73
-rw-r--r--src/include/MESA/field_stat2.h66
-rw-r--r--src/include/grule_for_view.h425
-rw-r--r--src/lib/libmaatframe.abin0 -> 1072618 bytes
-rw-r--r--src/load_table_info.hpp107
-rw-r--r--src/pg_valve_c3.cpp448
-rw-r--r--src/pg_valve_c3.h72
-rw-r--r--src/pg_valve_consul.cpp193
-rw-r--r--src/pg_valve_consul.h18
-rw-r--r--src/pg_valve_deal.cpp1429
-rw-r--r--src/pg_valve_deal.h141
-rw-r--r--src/pg_valve_maat.cpp138
-rw-r--r--src/pg_valve_maat.h51
-rw-r--r--src/pg_valve_main.cpp926
-rw-r--r--src/pg_valve_main.h134
-rw-r--r--src/pg_valve_stat.cpp490
-rw-r--r--src/pg_valve_stat.h85
-rw-r--r--src/pg_valve_tools.cpp44
-rw-r--r--src/pg_valve_tools.h13
-rw-r--r--src/support/c3client_double_20181020.tgzbin0 -> 266367 bytes
-rw-r--r--src/test_pg_valve.cpp101
-rw-r--r--tools/create_tuple_combine_macro.c115
105 files changed, 7673 insertions, 0 deletions
diff --git a/bin/conf/maat_cfg1/full/2018-06-16/APP_DOMAIN.0000000001 b/bin/conf/maat_cfg1/full/2018-06-16/APP_DOMAIN.0000000001
new file mode 100644
index 0000000..6fdb1af
--- /dev/null
+++ b/bin/conf/maat_cfg1/full/2018-06-16/APP_DOMAIN.0000000001
@@ -0,0 +1,3 @@
+2
+20001 2001 circuitiOS 0 0 0 1 APP_ID=100001;DOMAIN_ID=101
+20002 2002 circuitiOS 0 0 0 1 APP_ID=100002;DOMAIN_ID=102
diff --git a/bin/conf/maat_cfg1/full/2018-06-16/APP_POLICY.0000000001 b/bin/conf/maat_cfg1/full/2018-06-16/APP_POLICY.0000000001
new file mode 100644
index 0000000..53453aa
--- /dev/null
+++ b/bin/conf/maat_cfg1/full/2018-06-16/APP_POLICY.0000000001
@@ -0,0 +1,3 @@
+2
+10001 1001 circuitiOS 0 0 0 1 1 11 APP_ID=100001
+10002 1002 circuitiOS 0 0 0 1 1 11 APP_ID=100002
diff --git a/bin/conf/maat_cfg1/full/2018-07-10/LIMIT_DOMAIN.0000000001 b/bin/conf/maat_cfg1/full/2018-07-10/LIMIT_DOMAIN.0000000001
new file mode 100644
index 0000000..89378e9
--- /dev/null
+++ b/bin/conf/maat_cfg1/full/2018-07-10/LIMIT_DOMAIN.0000000001
@@ -0,0 +1,2 @@
+1
+10001 1001 circuitiOS 0 0 0 1 1 11 DOMAIN_ID=100001
diff --git a/bin/conf/maat_cfg1/full/full_config_index.0000000001 b/bin/conf/maat_cfg1/full/full_config_index.0000000001
new file mode 100644
index 0000000..69b8fab
--- /dev/null
+++ b/bin/conf/maat_cfg1/full/full_config_index.0000000001
@@ -0,0 +1,9 @@
+APP_DOMAIN 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg1/full/full_config_index.0000000001_real b/bin/conf/maat_cfg1/full/full_config_index.0000000001_real
new file mode 100644
index 0000000..d9a173c
--- /dev/null
+++ b/bin/conf/maat_cfg1/full/full_config_index.0000000001_real
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-07-10/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg1/full/index/full_config_index.0000000001 b/bin/conf/maat_cfg1/full/index/full_config_index.0000000001
new file mode 100644
index 0000000..69b8fab
--- /dev/null
+++ b/bin/conf/maat_cfg1/full/index/full_config_index.0000000001
@@ -0,0 +1,9 @@
+APP_DOMAIN 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/full/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000002 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000002
new file mode 100644
index 0000000..83a2ff8
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000002
@@ -0,0 +1,3 @@
+2
+20003 2003 circuitiOS 0 0 0 1 APP_ID=100003;DOMAIN_ID=103
+20004 2004 circuitiOS 0 0 0 1 APP_ID=100004;DOMAIN_ID=104
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000004 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000004
new file mode 100644
index 0000000..9ce8f98
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000004
@@ -0,0 +1,2 @@
+1
+20003 2003 circuitiOS 0 0 0 0 APP_ID=100003;DOMAIN_ID=103
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000005 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000005
new file mode 100644
index 0000000..0d27bec
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000005
@@ -0,0 +1,2 @@
+1
+20005 2005 circuitiOS 0 0 0 1 APP_ID=100005;DOMAIN_ID=105
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000007 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000007
new file mode 100644
index 0000000..d9514eb
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000007
@@ -0,0 +1,2 @@
+1
+20002 2002 circuitiOS 0 0 0 1 APP_ID=100002;DOMAIN_ID=102
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000008 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000008
new file mode 100644
index 0000000..5043606
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000008
@@ -0,0 +1,2 @@
+1
+20001 2001 circuitiOS 0 0 0 0 APP_ID=100001;DOMAIN_ID=101
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000009 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000009
new file mode 100644
index 0000000..f5311c3
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000009
@@ -0,0 +1,2 @@
+1
+20001 2001 circuitiOS 0 0 0 1 APP_ID=100001;DOMAIN_ID=101
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000003 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000003
new file mode 100644
index 0000000..b11d36a
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000003
@@ -0,0 +1,3 @@
+2
+10003 1003 circuitiOS 0 0 0 1 1 11 APP_ID=100003
+10004 1004 circuitiOS 0 0 0 1 1 11 APP_ID=100004
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000004 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000004
new file mode 100644
index 0000000..07d25ae
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000004
@@ -0,0 +1,2 @@
+1
+10004 1004 circuitiOS 0 0 0 0 1 11 APP_ID=100004
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000006 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000006
new file mode 100644
index 0000000..568d3a0
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000006
@@ -0,0 +1,2 @@
+1
+30005 3005 circuitiOS 0 0 0 1 1 11 APP_ID=100005
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000007 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000007
new file mode 100644
index 0000000..c594447
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000007
@@ -0,0 +1,2 @@
+1
+10001 1001 circuitiOS 0 0 0 0 1 11 APP_ID=100001
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000008 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000008
new file mode 100644
index 0000000..95e8035
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000008
@@ -0,0 +1,2 @@
+1
+10001 1001 circuitiOS 0 0 0 1 1 11 APP_ID=100001
diff --git a/bin/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000001 b/bin/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000001
new file mode 100644
index 0000000..2bab73a
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000001
@@ -0,0 +1,3 @@
+2
+40001 4001 4 192.168.10.197 255.255.255.255 0 65535 104.102.103.101 255.255.255.255 80 65535 6 1 1 APP_ID=100001;DOMAIN_ID=101
+40002 4002 4 192.168.10.198 255.255.255.255 0 65535 104.102.103.102 255.255.255.255 80 65535 6 1 1 APP_ID=100002;DOMAIN_ID=102
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000002 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000002
new file mode 100644
index 0000000..ae62de6
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000002
@@ -0,0 +1,9 @@
+APP_DOMAIN 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000002
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000002
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000002
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000002
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000002
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000002
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000002
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000002
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000002_bak b/bin/conf/maat_cfg1/inc/inc_config_index.0000000002_bak
new file mode 100644
index 0000000..8a2960b
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000002_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000008
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000008
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000008
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000008
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000008
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000008
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000008
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000008
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000002_real b/bin/conf/maat_cfg1/inc/inc_config_index.0000000002_real
new file mode 100644
index 0000000..ae62de6
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000002_real
@@ -0,0 +1,9 @@
+APP_DOMAIN 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000002
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000002
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000002
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000002
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000002
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000002
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000002
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000002
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000003 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000003
new file mode 100644
index 0000000..fab151f
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000003
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000003
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000003
+APP_POLICY 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000003
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000003
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000003
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000003
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000003
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000003
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000003_bak b/bin/conf/maat_cfg1/inc/inc_config_index.0000000003_bak
new file mode 100644
index 0000000..0ac2957
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000003_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000009
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000009
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000009
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000009
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000009
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000009
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000009
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000009
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000004 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000004
new file mode 100644
index 0000000..3dc6fd3
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000004
@@ -0,0 +1,9 @@
+APP_DOMAIN 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000004
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000004
+APP_POLICY 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000004
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000004
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000004
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000004
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000004
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000004
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000005 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000005
new file mode 100644
index 0000000..c43be99
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000005
@@ -0,0 +1,9 @@
+APP_DOMAIN 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000005
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000005
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000005
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000005
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000005
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000005
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000005
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000005
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000006 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000006
new file mode 100644
index 0000000..21bdbec
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000006
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000006
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000006
+APP_POLICY 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000006
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000006
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000006
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000006
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000006
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000006
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000007 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000007
new file mode 100644
index 0000000..12649b3
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000007
@@ -0,0 +1,9 @@
+APP_DOMAIN 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000007
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000007
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000007
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000007
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000007
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000007
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000007
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000007
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000008 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000008
new file mode 100644
index 0000000..dddbfdc
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000008
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 2 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000009 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000009
new file mode 100644
index 0000000..7d0582c
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000009
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000007
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000007
+APP_POLICY 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000007
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000007
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000007
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000007
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000007
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000007
+
diff --git a/bin/conf/maat_cfg1/inc/inc_config_index.0000000010 b/bin/conf/maat_cfg1/inc/inc_config_index.0000000010
new file mode 100644
index 0000000..b600536
--- /dev/null
+++ b/bin/conf/maat_cfg1/inc/inc_config_index.0000000010
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DOMAIN.0000000008
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000008
+APP_POLICY 1 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_POLICY.0000000008
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/APP_STATIC_SEV_IP.0000000008
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DOMAIN.0000000008
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000008
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_DYN_SERV_IP.0000000008
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg1/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000008
+
diff --git a/bin/conf/maat_cfg2/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001 b/bin/conf/maat_cfg2/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
new file mode 100644
index 0000000..7142c5d
--- /dev/null
+++ b/bin/conf/maat_cfg2/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
@@ -0,0 +1,3 @@
+2
+30001 4 6 192.168.11.198 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+30002 4 6 202.138.22.111 8800 1 APP_ID=100002;DOMAIN_ID=102 0 1
diff --git a/bin/conf/maat_cfg2/full/full_config_index.0000000001 b/bin/conf/maat_cfg2/full/full_config_index.0000000001
new file mode 100644
index 0000000..9914569
--- /dev/null
+++ b/bin/conf/maat_cfg2/full/full_config_index.0000000001
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 2 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg2/full/index/full_config_index.0000000001 b/bin/conf/maat_cfg2/full/index/full_config_index.0000000001
new file mode 100644
index 0000000..9914569
--- /dev/null
+++ b/bin/conf/maat_cfg2/full/index/full_config_index.0000000001
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 2 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/full/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000002 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000002
new file mode 100644
index 0000000..2f8276b
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000002
@@ -0,0 +1,3 @@
+2
+30003 4 6 122.188.44.198 8800 1 APP_ID=100003;DOMAIN_ID=103 0 1
+30004 4 6 123.134.33.111 8800 1 APP_ID=100004;DOMAIN_ID=104 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000003 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000003
new file mode 100644
index 0000000..7814e88
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000003
@@ -0,0 +1,2 @@
+1
+30001 4 6 192.168.11.198 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000004 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000004
new file mode 100644
index 0000000..886fc58
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000004
@@ -0,0 +1,2 @@
+1
+30003 4 6 122.188.44.198 8800 1 APP_ID=100003;DOMAIN_ID=103 0 0
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000005 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000005
new file mode 100644
index 0000000..93e12ac
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000005
@@ -0,0 +1,2 @@
+1
+30004 4 6 123.134.33.111 8800 1 APP_ID=100004;DOMAIN_ID=104 0 0
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000006 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000006
new file mode 100644
index 0000000..bed872e
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000006
@@ -0,0 +1,2 @@
+1
+30005 4 6 232.238.14.105 8800 2 APP_ID=100005;DOMAIN_ID=105 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000007 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000007
new file mode 100644
index 0000000..1bb4c62
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000007
@@ -0,0 +1,2 @@
+1
+31001 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000008 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000008
new file mode 100644
index 0000000..bf55b51
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000008
@@ -0,0 +1,11 @@
+10
+31002 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31003 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31004 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31005 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31006 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31007 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31008 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31009 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31010 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31011 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000009 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000009
new file mode 100644
index 0000000..8e323d4
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000009
@@ -0,0 +1,6 @@
+5
+31010 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31011 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31007 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31008 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31009 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000010 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000010
new file mode 100644
index 0000000..76197a0
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000010
@@ -0,0 +1,6 @@
+5
+31002 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31003 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31004 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31005 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
+31006 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000011 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000011
new file mode 100644
index 0000000..26ab5d9
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000011
@@ -0,0 +1,6 @@
+5
+31002 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31003 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31004 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31005 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
+31006 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 0
diff --git a/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000020 b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000020
new file mode 100644
index 0000000..041a20e
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000020
@@ -0,0 +1,2 @@
+1
+31002 4 6 122.188.44.101 8800 1 APP_ID=100001;DOMAIN_ID=101 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000001 b/bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000001
new file mode 100644
index 0000000..0c8aa88
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000001
@@ -0,0 +1,2 @@
+1
+30001 4 6 192.168.10.197 0 1 DOMAIN_ID=100001 0 1
diff --git a/bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000002 b/bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000002
new file mode 100644
index 0000000..ac96f56
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000002
@@ -0,0 +1,2 @@
+1
+30001 4 6 192.168.10.197 0 1 DOMAIN_ID=100001 0 0
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000002 b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002
new file mode 100644
index 0000000..6f023bb
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000002
+APP_DYN_SEV_IP_CB 2 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000002
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000002
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000002
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000002
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000002
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000002
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000002
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_bak b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_bak
new file mode 100644
index 0000000..daebaed
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000007
+APP_DYN_SEV_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000007
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000007
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000007
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000007
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000007
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000007
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000007
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_real b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_real
new file mode 100644
index 0000000..14b8459
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_real
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_DOMAIN.0000000001
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_DYN_SEV_IP_CB.0000000001
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_POLICY.0000000001
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_STATIC_SEV_IP.0000000001
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/LIMIT_DOMAIN.0000000001
+LIMIT_DYN_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000001
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/PXY_DYN_SERV_IP.0000000001
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/PXY_INTERCEPT_DOMAIN.0000000001
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_xxxxx b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_xxxxx
new file mode 100644
index 0000000..0cd1432
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000002_xxxxx
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000020
+APP_DYN_SEV_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000020
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000020
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000020
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000020
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000020
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000020
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000020
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000003 b/bin/conf/maat_cfg2/inc/inc_config_index.0000000003
new file mode 100644
index 0000000..8ed9c33
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000003
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000003
+APP_DYN_SEV_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000003
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000003
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000003
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000003
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000003
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000003
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000003
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000003_bak b/bin/conf/maat_cfg2/inc/inc_config_index.0000000003_bak
new file mode 100644
index 0000000..ac72846
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000003_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000008
+APP_DYN_SEV_IP_CB 10 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000008
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000008
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000008
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000008
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000008
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000008
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000008
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000003_real b/bin/conf/maat_cfg2/inc/inc_config_index.0000000003_real
new file mode 100644
index 0000000..1e670ba
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000003_real
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_DOMAIN.0000000002
+APP_DYN_SEV_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_DYN_SEV_IP_CB.0000000002
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_POLICY.0000000002
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/APP_STATIC_SEV_IP.0000000002
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/LIMIT_DOMAIN.0000000002
+LIMIT_DYN_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/LIMIT_DYN_IP_CB.0000000002
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/PXY_DYN_SERV_IP.0000000002
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-07-10/PXY_INTERCEPT_DOMAIN.0000000002
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000004 b/bin/conf/maat_cfg2/inc/inc_config_index.0000000004
new file mode 100644
index 0000000..fc9e53a
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000004
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000004
+APP_DYN_SEV_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000004
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000004
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000004
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000004
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000004
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000004
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000004
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000004_bak b/bin/conf/maat_cfg2/inc/inc_config_index.0000000004_bak
new file mode 100644
index 0000000..a649651
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000004_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000009
+APP_DYN_SEV_IP_CB 5 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000009
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000009
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000009
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000009
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000009
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000009
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000009
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000005 b/bin/conf/maat_cfg2/inc/inc_config_index.0000000005
new file mode 100644
index 0000000..3bd9679
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000005
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000005
+APP_DYN_SEV_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000005
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000005
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000005
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000005
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000005
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000005
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000005
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000005_bak b/bin/conf/maat_cfg2/inc/inc_config_index.0000000005_bak
new file mode 100644
index 0000000..41e71e5
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000005_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000010
+APP_DYN_SEV_IP_CB 5 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000010
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000010
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000010
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000010
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000010
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000010
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000010
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000006 b/bin/conf/maat_cfg2/inc/inc_config_index.0000000006
new file mode 100644
index 0000000..31e0b9e
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000006
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000006
+APP_DYN_SEV_IP_CB 1 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000006
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000006
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000006
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000006
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000006
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000006
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000006
+
diff --git a/bin/conf/maat_cfg2/inc/inc_config_index.0000000006_bak b/bin/conf/maat_cfg2/inc/inc_config_index.0000000006_bak
new file mode 100644
index 0000000..70ccc7d
--- /dev/null
+++ b/bin/conf/maat_cfg2/inc/inc_config_index.0000000006_bak
@@ -0,0 +1,9 @@
+APP_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DOMAIN.0000000011
+APP_DYN_SEV_IP_CB 5 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_DYN_SEV_IP_CB.0000000011
+APP_POLICY 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_POLICY.0000000011
+APP_STATIC_SEV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/APP_STATIC_SEV_IP.0000000011
+LIMIT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DOMAIN.0000000011
+LIMIT_DYN_IP_CB 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/LIMIT_DYN_IP_CB.0000000011
+PXY_DYN_SERV_IP 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_DYN_SERV_IP.0000000011
+PXY_INTERCEPT_DOMAIN 0 /home/mesasoft/pangu_valve/conf/maat_cfg2/inc/2018-06-16/PXY_INTERCEPT_DOMAIN.0000000011
+
diff --git a/bin/conf/maat_table_info.conf b/bin/conf/maat_table_info.conf
new file mode 100644
index 0000000..055e9a8
--- /dev/null
+++ b/bin/conf/maat_table_info.conf
@@ -0,0 +1,24 @@
+#each collumn seperate with '\t'
+#id (0~65535(
+#name string
+#type one of ip,expr,compile or plugin
+#src_charset one of GBK,BIG5,UNICODE,UTF8
+#dst_charset combined by GBK,BIG5,UNICODE,UTF8,seperate with '/'
+#do_merege yes or no
+#id name type IS_VALID_INDEX
+0 APP_DOMAIN plugin 7
+1 APP_DYN_SEV_IP_CB plugin 9
+2 APP_POLICY plugin 7
+3 APP_STATIC_SEV_IP plugin 14
+4 LIMIT_DOMAIN plugin 7
+5 LIMIT_DYN_IP_CB plugin 9
+6 PXY_DYN_SEV_IP_CB plugin 9
+7 PXY_INTERCEPT_DOMAIN plugin 7
+8 LIMIT_IP plugin 14
+9 PXY_INTERCEPT_IP plugin 14
+10 INLINE_IP_CB plugin 14
+11 IR_STATIC_IP_POOL_CB plugin 9
+12 DK_CLI_IP_CB plugin 14
+13 IPD_DYN_SUBSCIBE_IP plugin 9
+14 IR_DYN_SIFT_IP plugin 9
+15 ANTI_DDOS_ATTACK_CB plugin 14
diff --git a/bin/conf/pangu_valve.conf b/bin/conf/pangu_valve.conf
new file mode 100644
index 0000000..cb158a9
--- /dev/null
+++ b/bin/conf/pangu_valve.conf
@@ -0,0 +1,30 @@
+[SYSTEM]
+C3_AUTH_DATA=B9840E2442951834
+C3_CCC_LISTS=10.3.48.1:10005;
+
+HASH_TABLE_SIZE=8388608
+SW_HNODE_TIMEOUT_MIN=1
+#1-file; 2-redis
+MAAT_CONFIG_RECV_WAY=2
+MAAT_TABLE_INFO_PATH=./conf/maat_table_info.conf
+
+CONSUL_SWITCH=0
+CONSUL_REQ_TIMEOUT=4
+CONSUL_LOCK_DELAY=5
+CONSUL_SESSION_TTL=10
+CONSUL_LEADER_KEY=PANGU_VALVE/valve_leader01
+LOCAL_NET_NAME=eth2
+SERVICE_TOPLIMIT_SW=0
+
+[LOG]
+RUN_LOG_DIR=./log
+RUN_LOG_LV=10
+#ASMIS_PROC_NAME=PANGU/valve
+#ASMIS_HEART_INTERVAL=10
+FS_STAT_APPNAME=PANGU_VALVE
+STATISTIC_INTERVAL=60
+FS_STAT_MODE=1
+FS_STAT_DST_IP=10.172.128.2
+FS_STAT_DST_PORT=8125
+FS_STAT_TRIG=1
+
diff --git a/bin/conf/table_info/maat_info.conf b/bin/conf/table_info/maat_info.conf
new file mode 100644
index 0000000..d0eeeee
--- /dev/null
+++ b/bin/conf/table_info/maat_info.conf
@@ -0,0 +1,6 @@
+#INS_NAME MAAT_ROOT VERSION_FILE REDIS_IP RPORT RINDEX TABLE_NAMES_LIST
+STATIC ./conf/maat_cfg1/ ./conf/version_static.txt 10.3.34.1 6379 5 APP_POLICY;APP_DOMAIN;PXY_INTERCEPT_DOMAIN;LIMIT_DOMAIN;APP_STATIC_SEV_IP;LIMIT_IP;PXY_INTERCEPT_IP;INLINE_IP_CB;IR_STATIC_IP_POOL_CB
+DYNAMIC1 ./conf/maat_cfg2/ ./conf/version_dynamic2.txt 10.3.47.1 6379 0 ANTI_DDOS_ATTACK_CB;IR_DYN_SIFT_IP
+DYNAMIC2 ./conf/maat_cfg2/ ./conf/version_dynamic2.txt 10.3.47.1 6379 1 APP_DYN_SEV_IP_CB;PXY_DYN_SEV_IP_CB;LIMIT_DYN_IP_CB;IPD_DYN_SUBSCIBE_IP
+DYNAMIC3 ./conf/maat_cfg2/ ./conf/version_dynamic3.txt 10.3.47.1 6379 2 DK_CLI_IP_CB
+
diff --git a/bin/conf/table_info/service_id_map.conf b/bin/conf/table_info/service_id_map.conf
new file mode 100644
index 0000000..82f448a
--- /dev/null
+++ b/bin/conf/table_info/service_id_map.conf
@@ -0,0 +1,40 @@
+#service_id limit_rate grule_serv_type RULE_SCOPE limit_num
+#INLINE_IP_CB DROP
+3 0 10 1 1000
+#ANTIDDOS DROP
+5 0 7 1 1000
+#INLINE_IP_CB DROP IPSEC/GRE 0x19/0x1C
+25 0 10 1 1000
+28 0 10 1 1000
+
+#IR_STATIC_IP_POOL LOOP 0x340
+832 0 20 1 1000
+#IR_DYN_SIFT_IP LOOP 0x341
+833 0 19 1 1000
+
+#PXY_INTERCEPT_IP MONITOR 0x200/0x202/0x205
+512 0 21 1 1000
+514 0 21 1 1000
+517 0 21 1 1000
+#PXY_INTERCEPT_DOMAIN MONITOR 0x201
+513 0 22 1 1000
+
+#APP_POLICY REJECT 0x21
+33 0 8 1 1000
+#APP_POLICY MONITOR 0x91
+145 0 18 1 1000
+#IPD_DYN_SUBSCIBE_IP
+#DK_CLI_IP_CB
+1045 0 18 1 1000
+#APP_POLICY DROP 0x410
+1040 0 8 1 1000
+##APP_POLICY LIMIT 0x420
+1056 0 246 1 1000
+1056 10 247 1 1000
+1056 20 248 1 1000
+1056 30 249 1 1000
+1056 40 250 1 1000
+
+#TEST
+11 0 8 1 10
+
diff --git a/bin/conf/table_info/service_id_map_test.conf b/bin/conf/table_info/service_id_map_test.conf
new file mode 100644
index 0000000..c46a0ef
--- /dev/null
+++ b/bin/conf/table_info/service_id_map_test.conf
@@ -0,0 +1,67 @@
+#service_id grule_serv_type RULE_SCOPE limit_num
+#INLINE_IP_CB DROP
+3 0 1 1 1000
+#INLINE_IP_CB LOOP
+4 0 1 1 1000
+#ANTIDDOS
+5 0 1 1 1000
+#INLINE_IP_CB DROP IPSEC 0x19/0x1D
+25 0 1 1 1000
+29 0 1 1 1000
+#INLINE_IP_CB DROP GRE 0x1C
+28 0 1 1 1000
+
+#IR_STATIC_IP_POOL LOOP 0x340
+832 0 1 1 1000
+#IR_DYN_SIFT_IP LOOP 0x341
+833 0 1 1 1000
+
+#PXY_INTERCEPT_IP MONITOR 0x200
+512 0 1 1 1000
+#PXY_INTERCEPT_DOMAIN MONITOR 0x201
+513 0 1 1 1000
+
+#APP_POLICY REJECT 0x21
+33 0 1 1 1000
+#APP_POLICY MONITOR 0x91
+145 0 1 1 1000
+#APP_POLICY DROP 0x410
+1040 0 1 1 1000
+#APP_POLICY LIMIT 0x420
+1056 10 1 1 1000
+1056 20 1 1 1000
+1056 30 1 1 1000
+1056 40 1 1 1000
+1056 50 1 1 1000
+1056 60 1 1 1000
+1056 70 1 1 1000
+1056 80 1 1 1000
+1056 90 1 1 1000
+1056 100 1 1 1000
+
+#LIMIT_IP 0x421
+1057 10 1 1 1000
+1057 20 1 1 1000
+1057 30 1 1 1000
+1057 40 1 1 1000
+1057 50 1 1 1000
+1057 60 1 1 1000
+1057 70 1 1 1000
+1057 80 1 1 1000
+1057 90 1 1 1000
+1057 100 1 1 1000
+#LIMIT_DOMAIN 0x422
+1058 10 1 1 1000
+1058 20 1 1 1000
+1058 30 1 1 1000
+1058 40 1 1 1000
+1058 50 1 1 1000
+1058 60 1 1 1000
+1058 70 1 1 1000
+1058 80 1 1 1000
+1058 90 1 1 1000
+1058 100 1 1 1000
+
+#TEST
+11 0 2 1 10
+
diff --git a/bin/conf/table_info/table_info_one.conf b/bin/conf/table_info/table_info_one.conf
new file mode 100644
index 0000000..8d76f65
--- /dev/null
+++ b/bin/conf/table_info/table_info_one.conf
@@ -0,0 +1,10 @@
+#table_one:tabid servid type
+LIMIT_IP:1 5 REGION_TYPE_IP
+PXY_INTERCEPT_IP:2 6 REGION_TYPE_IP
+INLINE_IP_CB:3 7 REGION_TYPE_IP
+IR_STATIC_IP_POOL_CB:4 8 REGION_TYPE_POOL
+DK_CLI_IP_CB:5 9 REGION_TYPE_IP
+IPD_DYN_SUBSCIBE_IP:6 10 REGION_TYPE_POOL
+IR_DYN_SIFT_IP:7 11 REGION_TYPE_POOL
+ANTI_DDOS_ATTACK_CB:8 12 REGION_TYPE_IP
+
diff --git a/bin/conf/table_info/table_info_tree.conf b/bin/conf/table_info/table_info_tree.conf
new file mode 100644
index 0000000..1dab0db
--- /dev/null
+++ b/bin/conf/table_info/table_info_tree.conf
@@ -0,0 +1,6 @@
+#three two onesw servid type
+APP_POLICY:11 APP_DOMAIN:12 APP_DYN_SEV_IP_CB:13 1 REGION_TYPE_FIND
+APP_POLICY:11 NULL APP_STATIC_SEV_IP:14 2 REGION_TYPE_IP
+NULL PXY_INTERCEPT_DOMAIN:15 PXY_DYN_SEV_IP_CB:16 3 REGION_TYPE_FIND
+NULL LIMIT_DOMAIN:17 LIMIT_DYN_IP_CB:18 4 REGION_TYPE_FIND
+
diff --git a/bin/firstconnect.txt b/bin/firstconnect.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/firstconnect.txt
diff --git a/bin/memchk.sh b/bin/memchk.sh
new file mode 100644
index 0000000..de01bd8
--- /dev/null
+++ b/bin/memchk.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+valgrind --tool=memcheck --leak-check=full --undef-value-errors=yes --leak-resolution=high --malloc-fill=AA --free-fill=FE --log-file=valgrind.log $1
diff --git a/bin/pangu_valve b/bin/pangu_valve
new file mode 100644
index 0000000..4b468d0
--- /dev/null
+++ b/bin/pangu_valve
Binary files differ
diff --git a/bin/pangu_valve_dmn.sh b/bin/pangu_valve_dmn.sh
new file mode 100644
index 0000000..58ebf23
--- /dev/null
+++ b/bin/pangu_valve_dmn.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+while [ 1 ];
+do
+ count=`ls -l core.* |wc -l`
+ echo $count
+ if [ $count -lt 3 ]
+ then
+ echo "set unlimited"
+ ulimit -c unlimited
+ else
+ ulimit -c 0
+ fi
+
+ ./pangu_valve >> /dev/null
+ retval=$?
+ if [ $retval == 10 ]; then
+ echo program receives full, restart at `date +"%w %Y/%m/%d, %H:%M:%S"` >> RESTART.log
+ elif [ $retval == 20 ]; then
+ echo program already running, restart at `date +"%w %Y/%m/%d, %H:%M:%S"` >> RESTART.log
+ else
+ echo program crashed, restart at `date +"%w %Y/%m/%d, %H:%M:%S"` >> RESTART.log
+ fi
+ sleep 30
+done
+
diff --git a/bin/pangu_valve_start.sh b/bin/pangu_valve_start.sh
new file mode 100644
index 0000000..be2c4d7
--- /dev/null
+++ b/bin/pangu_valve_start.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+killall pangu_valve_dmn.sh pangu_valve
+./pangu_valve_dmn.sh &>/dev/null &
diff --git a/bin/pangu_valve_stop.sh b/bin/pangu_valve_stop.sh
new file mode 100644
index 0000000..03ef3f9
--- /dev/null
+++ b/bin/pangu_valve_stop.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+killall pangu_valve_dmn.sh pangu_valve
diff --git a/bin/pangu_valve_test b/bin/pangu_valve_test
new file mode 100644
index 0000000..bf0091b
--- /dev/null
+++ b/bin/pangu_valve_test
Binary files differ
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..b7c1dea
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,41 @@
+CCC=g++
+
+VPATH+=./cJSON
+INC_PATH=-I./include -I./cJSON
+CFLAGS=-Wall -g $(INC_PATH)
+LDFLAGS =
+LIBS = -lMESA_handle_logger -lMESA_htable -lMESA_prof_load -lMESA_field_stat2 -lasmislog -lwiredcfg
+LIBS += -lmaatframe
+#LIBS += ./lib/libmaatframe.a
+LIBS += -lrulescan -lpcre -lhiredis_vip -lssl -lcrypto -lcurl
+LIBS +=-lpthread
+LIBS_TEST:=$(LIBS)
+LIBS += -lc3client_ok
+
+OBJS = cJSON.o check_ip_legal.o pg_valve_consul.o pg_valve_tools.o pg_valve_stat.o pg_valve_c3.o pg_valve_deal.o pg_valve_maat.o pg_valve_main.o
+OBJS_TEST= test_pg_valve.o $(OBJS)
+DEPS = $(OBJS:.o=.d)
+
+TARGET_EXE=pangu_valve
+TARGET_EXE_TEST=pangu_valve_test
+
+ALL:$(TARGET_EXE) $(TARGET_EXE_TEST)
+
+$(TARGET_EXE):$(OBJS)
+ $(CCC) $(LDFLAGS) $^ -o $@ $(LIBS)
+ cp $@ ../bin/
+
+$(TARGET_EXE_TEST):$(OBJS_TEST)
+ $(CCC) $(LDFLAGS) $^ -o $@ $(LIBS_TEST)
+ cp $@ ../bin/
+
+.cpp.o:
+ $(CCC) $(CFLAGS) -c $<
+
+.c.o:
+ $(CCC) $(CFLAGS) -c $<
+
+-include $(DEPS)
+
+clean:
+ rm -rf $(OBJS_TEST) $(DEPS) $(TARGET_EXE) $(TARGET_EXE_TEST)
diff --git a/src/cJSON/cJSON.c b/src/cJSON/cJSON.c
new file mode 100644
index 0000000..35452cb
--- /dev/null
+++ b/src/cJSON/cJSON.c
@@ -0,0 +1,596 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/* cJSON */
+/* JSON parser in C. */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include <limits.h>
+#include <ctype.h>
+#include "cJSON.h"
+
+static const char *ep;
+
+const char *cJSON_GetErrorPtr(void) {return ep;}
+
+static int cJSON_strcasecmp(const char *s1,const char *s2)
+{
+ if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
+ for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
+ return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
+}
+
+static void *(*cJSON_malloc)(size_t sz) = malloc;
+static void (*cJSON_free)(void *ptr) = free;
+
+static char* cJSON_strdup(const char* str)
+{
+ size_t len;
+ char* copy;
+
+ len = strlen(str) + 1;
+ if (!(copy = (char*)cJSON_malloc(len))) return 0;
+ memcpy(copy,str,len);
+ return copy;
+}
+
+void cJSON_InitHooks(cJSON_Hooks* hooks)
+{
+ if (!hooks) { /* Reset hooks */
+ cJSON_malloc = malloc;
+ cJSON_free = free;
+ return;
+ }
+
+ cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
+ cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item(void)
+{
+ cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
+ if (node) memset(node,0,sizeof(cJSON));
+ return node;
+}
+
+/* Delete a cJSON structure. */
+void cJSON_Delete(cJSON *c)
+{
+ cJSON *next;
+ while (c)
+ {
+ next=c->next;
+ if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
+ if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
+ if (c->string) cJSON_free(c->string);
+ cJSON_free(c);
+ c=next;
+ }
+}
+
+/* Parse the input text to generate a number, and populate the result into item. */
+static const char *parse_number(cJSON *item,const char *num)
+{
+ double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
+
+ if (*num=='-') sign=-1,num++; /* Has sign? */
+ if (*num=='0') num++; /* is zero */
+ if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
+ if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
+ if (*num=='e' || *num=='E') /* Exponent? */
+ { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
+ while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
+ }
+
+ n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
+
+ item->valuedouble=n;
+ item->valueint=(int)n;
+ item->type=cJSON_Number;
+ return num;
+}
+
+/* Render the number nicely from the given item into a string. */
+static char *print_number(cJSON *item)
+{
+ char *str;
+ double d=item->valuedouble;
+ if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
+ {
+ str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
+ if (str) sprintf(str,"%d",item->valueint);
+ }
+ else
+ {
+ str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
+ if (str)
+ {
+ if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
+ else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
+ else sprintf(str,"%f",d);
+ }
+ }
+ return str;
+}
+
+static unsigned parse_hex4(const char *str)
+{
+ unsigned h=0;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ return h;
+}
+
+/* Parse the input text into an unescaped cstring, and populate item. */
+static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+static const char *parse_string(cJSON *item,const char *str)
+{
+ const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+ if (*str!='\"') {ep=str;return 0;} /* not a string! */
+
+ while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
+
+ out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
+ if (!out) return 0;
+
+ ptr=str+1;ptr2=out;
+ while (*ptr!='\"' && *ptr)
+ {
+ if (*ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ ptr++;
+ switch (*ptr)
+ {
+ case 'b': *ptr2++='\b'; break;
+ case 'f': *ptr2++='\f'; break;
+ case 'n': *ptr2++='\n'; break;
+ case 'r': *ptr2++='\r'; break;
+ case 't': *ptr2++='\t'; break;
+ case 'u': /* transcode utf16 to utf8. */
+ uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
+
+ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
+
+ if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
+ {
+ if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
+ uc2=parse_hex4(ptr+3);ptr+=6;
+ if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
+ uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
+ }
+
+ len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
+
+ switch (len) {
+ case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 1: *--ptr2 =(uc | firstByteMark[len]);
+ }
+ ptr2+=len;
+ break;
+ default: *ptr2++=*ptr; break;
+ }
+ ptr++;
+ }
+ }
+ *ptr2=0;
+ if (*ptr=='\"') ptr++;
+ item->valuestring=out;
+ item->type=cJSON_String;
+ return ptr;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static char *print_string_ptr(const char *str)
+{
+ const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
+
+ if (!str) return cJSON_strdup("");
+ ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
+
+ out=(char*)cJSON_malloc(len+3);
+ if (!out) return 0;
+
+ ptr2=out;ptr=str;
+ *ptr2++='\"';
+ while (*ptr)
+ {
+ if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ *ptr2++='\\';
+ switch (token=*ptr++)
+ {
+ case '\\': *ptr2++='\\'; break;
+ case '\"': *ptr2++='\"'; break;
+ case '\b': *ptr2++='b'; break;
+ case '\f': *ptr2++='f'; break;
+ case '\n': *ptr2++='n'; break;
+ case '\r': *ptr2++='r'; break;
+ case '\t': *ptr2++='t'; break;
+ default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
+ }
+ }
+ }
+ *ptr2++='\"';*ptr2++=0;
+ return out;
+}
+/* Invote print_string_ptr (which is useful) on an item. */
+static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
+
+/* Predeclare these prototypes. */
+static const char *parse_value(cJSON *item,const char *value);
+static char *print_value(cJSON *item,int depth,int fmt);
+static const char *parse_array(cJSON *item,const char *value);
+static char *print_array(cJSON *item,int depth,int fmt);
+static const char *parse_object(cJSON *item,const char *value);
+static char *print_object(cJSON *item,int depth,int fmt);
+
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
+
+/* Parse an object - create a new root, and populate. */
+cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
+{
+ const char *end=0;
+ cJSON *c=cJSON_New_Item();
+ ep=0;
+ if (!c) return 0; /* memory fail */
+
+ end=parse_value(c,skip(value));
+ if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
+
+ /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
+ if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
+ if (return_parse_end) *return_parse_end=end;
+ return c;
+}
+/* Default options for cJSON_Parse */
+cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
+
+/* Render a cJSON item/entity/structure to text. */
+char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
+char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
+
+/* Parser core - when encountering text, process appropriately. */
+static const char *parse_value(cJSON *item,const char *value)
+{
+ if (!value) return 0; /* Fail on null. */
+ if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
+ if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
+ if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
+ if (*value=='\"') { return parse_string(item,value); }
+ if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
+ if (*value=='[') { return parse_array(item,value); }
+ if (*value=='{') { return parse_object(item,value); }
+
+ ep=value;return 0; /* failure. */
+}
+
+/* Render a value to text. */
+static char *print_value(cJSON *item,int depth,int fmt)
+{
+ char *out=0;
+ if (!item) return 0;
+ switch ((item->type)&255)
+ {
+ case cJSON_NULL: out=cJSON_strdup("null"); break;
+ case cJSON_False: out=cJSON_strdup("false");break;
+ case cJSON_True: out=cJSON_strdup("true"); break;
+ case cJSON_Number: out=print_number(item);break;
+ case cJSON_String: out=print_string(item);break;
+ case cJSON_Array: out=print_array(item,depth,fmt);break;
+ case cJSON_Object: out=print_object(item,depth,fmt);break;
+ }
+ return out;
+}
+
+/* Build an array from input text. */
+static const char *parse_array(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='[') {ep=value;return 0;} /* not an array! */
+
+ item->type=cJSON_Array;
+ value=skip(value+1);
+ if (*value==']') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0; /* memory fail */
+ value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_value(child,skip(value+1)));
+ if (!value) return 0; /* memory fail */
+ }
+
+ if (*value==']') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an array to text */
+static char *print_array(cJSON *item,int depth,int fmt)
+{
+ char **entries;
+ char *out=0,*ptr,*ret;int len=5;
+ cJSON *child=item->child;
+ int numentries=0,i=0,fail=0;
+
+ /* How many entries in the array? */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle numentries==0 */
+ if (!numentries)
+ {
+ out=(char*)cJSON_malloc(3);
+ if (out) strcpy(out,"[]");
+ return out;
+ }
+ /* Allocate an array to hold the values for each */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ memset(entries,0,numentries*sizeof(char*));
+ /* Retrieve all the results: */
+ child=item->child;
+ while (child && !fail)
+ {
+ ret=print_value(child,depth+1,fmt);
+ entries[i++]=ret;
+ if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
+ child=child->next;
+ }
+
+ /* If we didn't fail, try to malloc the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ /* If that fails, we fail. */
+ if (!out) fail=1;
+
+ /* Handle failure. */
+ if (fail)
+ {
+ for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
+ cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output array. */
+ *out='[';
+ ptr=out+1;*ptr=0;
+ for (i=0;i<numentries;i++)
+ {
+ strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
+ if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
+ cJSON_free(entries[i]);
+ }
+ cJSON_free(entries);
+ *ptr++=']';*ptr++=0;
+ return out;
+}
+
+/* Build an object from the text. */
+static const char *parse_object(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='{') {ep=value;return 0;} /* not an object! */
+
+ item->type=cJSON_Object;
+ value=skip(value+1);
+ if (*value=='}') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0;
+ value=skip(parse_string(child,skip(value)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_string(child,skip(value+1)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+ }
+
+ if (*value=='}') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an object to text. */
+static char *print_object(cJSON *item,int depth,int fmt)
+{
+ char **entries=0,**names=0;
+ char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
+ cJSON *child=item->child;
+ int numentries=0,fail=0;
+ /* Count the number of entries. */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle empty object case */
+ if (!numentries)
+ {
+ out=(char*)cJSON_malloc(fmt?depth+4:3);
+ if (!out) return 0;
+ ptr=out;*ptr++='{';
+ if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
+ *ptr++='}';*ptr++=0;
+ return out;
+ }
+ /* Allocate space for the names and the objects */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ names=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!names) {cJSON_free(entries);return 0;}
+ memset(entries,0,sizeof(char*)*numentries);
+ memset(names,0,sizeof(char*)*numentries);
+
+ /* Collect all the results into our arrays: */
+ child=item->child;depth++;if (fmt) len+=depth;
+ while (child)
+ {
+ names[i]=str=print_string_ptr(child->string);
+ entries[i++]=ret=print_value(child,depth,fmt);
+ if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
+ child=child->next;
+ }
+
+ /* Try to allocate the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ if (!out) fail=1;
+
+ /* Handle failure */
+ if (fail)
+ {
+ for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
+ cJSON_free(names);cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output: */
+ *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
+ for (i=0;i<numentries;i++)
+ {
+ if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
+ strcpy(ptr,names[i]);ptr+=strlen(names[i]);
+ *ptr++=':';if (fmt) *ptr++='\t';
+ strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
+ if (i!=numentries-1) *ptr++=',';
+ if (fmt) *ptr++='\n';*ptr=0;
+ cJSON_free(names[i]);cJSON_free(entries[i]);
+ }
+
+ cJSON_free(names);cJSON_free(entries);
+ if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
+ *ptr++='}';*ptr++=0;
+ return out;
+}
+
+/* Get Array size/item / object item. */
+int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
+cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
+cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
+
+/* Add item to array/object. */
+void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
+void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
+
+cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
+ if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
+void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
+cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
+void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
+
+/* Replace array/object items with new ones. */
+void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
+ newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
+ if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
+void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
+
+/* Create basic types: */
+cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
+cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
+cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
+cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
+cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
+cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
+cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
+cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
+
+/* Create Arrays: */
+cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+
+/* Duplication */
+cJSON *cJSON_Duplicate(cJSON *item,int recurse)
+{
+ cJSON *newitem,*cptr,*nptr=0,*newchild;
+ /* Bail on bad ptr */
+ if (!item) return 0;
+ /* Create new item */
+ newitem=cJSON_New_Item();
+ if (!newitem) return 0;
+ /* Copy over all vars */
+ newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
+ if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
+ if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
+ /* If non-recursive, then we're done! */
+ if (!recurse) return newitem;
+ /* Walk the ->next chain for the child. */
+ cptr=item->child;
+ while (cptr)
+ {
+ newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
+ if (!newchild) {cJSON_Delete(newitem);return 0;}
+ if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
+ else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
+ cptr=cptr->next;
+ }
+ return newitem;
+}
+
+void cJSON_Minify(char *json)
+{
+ char *into=json;
+ while (*json)
+ {
+ if (*json==' ') json++;
+ else if (*json=='\t') json++; // Whitespace characters.
+ else if (*json=='\r') json++;
+ else if (*json=='\n') json++;
+ else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
+ else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
+ else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
+ else *into++=*json++; // All other characters.
+ }
+ *into=0; // and null-terminate.
+}
diff --git a/src/cJSON/cJSON.h b/src/cJSON/cJSON.h
new file mode 100644
index 0000000..867b7c3
--- /dev/null
+++ b/src/cJSON/cJSON.h
@@ -0,0 +1,143 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* cJSON Types: */
+#define cJSON_False 0
+#define cJSON_True 1
+#define cJSON_NULL 2
+#define cJSON_Number 3
+#define cJSON_String 4
+#define cJSON_Array 5
+#define cJSON_Object 6
+
+#define cJSON_IsReference 256
+
+/* The cJSON structure: */
+typedef struct cJSON {
+ struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+ struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+
+ int type; /* The type of the item, as above. */
+
+ char *valuestring; /* The item's string, if type==cJSON_String */
+ int valueint; /* The item's number, if type==cJSON_Number */
+ double valuedouble; /* The item's number, if type==cJSON_Number */
+
+ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+} cJSON;
+
+typedef struct cJSON_Hooks {
+ void *(*malloc_fn)(size_t sz);
+ void (*free_fn)(void *ptr);
+} cJSON_Hooks;
+
+/* Supply malloc, realloc and free functions to cJSON */
+extern void cJSON_InitHooks(cJSON_Hooks* hooks);
+
+
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
+extern cJSON *cJSON_Parse(const char *value);
+/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
+extern char *cJSON_Print(cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
+extern char *cJSON_PrintUnformatted(cJSON *item);
+/* Delete a cJSON entity and all subentities. */
+extern void cJSON_Delete(cJSON *c);
+
+/* Returns the number of items in an array (or object). */
+extern int cJSON_GetArraySize(cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
+/* Get item "string" from object. Case insensitive. */
+extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+extern const char *cJSON_GetErrorPtr(void);
+
+/* These calls create a cJSON item of the appropriate type. */
+extern cJSON *cJSON_CreateNull(void);
+extern cJSON *cJSON_CreateTrue(void);
+extern cJSON *cJSON_CreateFalse(void);
+extern cJSON *cJSON_CreateBool(int b);
+extern cJSON *cJSON_CreateNumber(double num);
+extern cJSON *cJSON_CreateString(const char *string);
+extern cJSON *cJSON_CreateArray(void);
+extern cJSON *cJSON_CreateObject(void);
+
+/* These utilities create an Array of count items. */
+extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
+extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
+extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
+extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
+
+/* Append item to the specified array/object. */
+extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
+extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
+extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
+extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
+
+/* Update array items. */
+extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
+extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+
+/* Duplicate a cJSON item */
+extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
+/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
+need to be released. With recurse!=0, it will duplicate any children connected to the item.
+The item->next and ->prev pointers are always zero on return from Duplicate. */
+
+/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
+extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
+
+extern void cJSON_Minify(char *json);
+
+/* Macros for creating things quickly. */
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+
+/* When assigning an integer value, it needs to be propagated to valuedouble too. */
+#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/check_ip_legal.c b/src/check_ip_legal.c
new file mode 100644
index 0000000..cf45fcc
--- /dev/null
+++ b/src/check_ip_legal.c
@@ -0,0 +1,241 @@
+#include "check_ip_legal.h"
+
+
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+typedef union ip6_addr {
+ uint8_t c[16];
+ uint16_t s[8];
+ uint32_t i[4];
+ uint64_t l[2];
+}__attribute((aligned(16)))ip6_addr_t;
+
+typedef struct ip6_addr_l{
+ uint8_t c[16];
+}__attribute((aligned(16)))ip6_addr_l_t;
+
+
+int ipv6_valid(uint8_t * ipv6)
+{
+ return IPV6_OK;
+ /*if((ipv6[0] & 0xE0) == 0x20){ // globle unicast
+ return IPV6_OK;
+ }
+ return IPV6_ILLEGAL;*/
+}
+
+
+
+static const ip6_addr_l_t IP6_MASK[]={
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe },
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
+};
+
+inline int ipv6mp_valid(uint8_t * ipv6, uint8_t prefix)
+{
+ ip6_addr_t * mask;
+ ip6_addr_t * src;
+
+ if(prefix < IPV6_PREFIX_MIN || prefix > 128){
+ return IPV6_PREFIX_LEN_ERR;
+ }
+
+ if(ipv6_valid(ipv6) != IPV6_OK){
+ return IPV6_ILLEGAL;
+ }
+
+ src = (ip6_addr_t*) ipv6;
+ mask = (ip6_addr_t*) &IP6_MASK[prefix];
+
+ if(unlikely(((src->l[0] & mask->l[0]) != src->l[0]) || ((src->l[1] & mask->l[1]) != src->l[1])) ){
+ return IPV6_IP_PREFIX_ERR;
+ }
+
+ return IPV6_OK;
+}
+
+uint8_t UINT8_MASK[] = {0x00, 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
+
+int ipv6m_valid(uint8_t * ipv6, uint8_t * mask)
+{
+ int i,j;
+ ip6_addr_t * _mask;
+ int prefix;
+ uint8_t m;
+ ip6_addr_t * src;
+
+ _mask = (ip6_addr_t*) mask;
+
+ prefix = 0;
+ for(i = 0; i < 16; i++){
+ if(likely(_mask->c[i] == 0xff)){
+ prefix += 8;
+ continue;
+ }
+ break;
+ }
+
+ if(i < 16){
+ m = _mask->c[i];
+ for(j = 0; j < 8; j++){
+ if(m == UINT8_MASK[j]){
+ break;
+ }
+ prefix++;
+ }
+ if(unlikely(j >= 8)){
+ return IPV6_PREFIX_NONPRE;
+ }
+ }
+
+ for(; i < 16; i++){
+ if(_mask->c[i] != 0){
+ return IPV6_PREFIX_ERR;
+ }
+ }
+
+
+ if(prefix < IPV6_PREFIX_MIN || prefix > 128){
+ return IPV6_PREFIX_LEN_ERR;
+ }
+ src = (ip6_addr_t*) ipv6;
+ if(unlikely(((src->l[0] & _mask->l[0]) != src->l[0]) || ((src->l[1] & _mask->l[1]) != src->l[1])) ){
+ return IPV6_IP_PREFIX_ERR;
+ }
+
+ return IPV6_OK;
+
+}
+
diff --git a/src/check_ip_legal.h b/src/check_ip_legal.h
new file mode 100644
index 0000000..86a5bc4
--- /dev/null
+++ b/src/check_ip_legal.h
@@ -0,0 +1,33 @@
+#ifndef __CHECK_IP_LEGAL_H__
+#define __CHECK_IP_LEGAL_H__
+
+#if defined __GNUC__ || defined __llvm__
+#define likely(x) __builtin_expect ((x), 1)
+#define unlikely(x) __builtin_expect ((x), 0)
+#else
+#define likely(x) (x)
+#define unlikely(x) (x)
+#endif
+
+
+#ifndef IPV6_PREFIX_MIN
+ #define IPV6_PREFIX_MIN 48
+#endif
+
+#define IPV6_OK 0
+#define IPV6_ILLEGAL 2
+#define IPV6_PREFIX_LEN_ERR 3
+#define IPV6_PREFIX_NONPRE 4 //ǰ׺���벻��
+#define IPV6_PREFIX_ERR 5 //ͬ4
+#define IPV6_IP_PREFIX_ERR 6 //�ڹ��󲻵����Լ�
+
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern int ipv6_valid(uint8_t * ipv6);
+extern int ipv6m_valid(uint8_t * ipv6, uint8_t * mask);
+
+#endif
+
diff --git a/src/include/MESA/MESA_handle_logger.h b/src/include/MESA/MESA_handle_logger.h
new file mode 100644
index 0000000..c615b53
--- /dev/null
+++ b/src/include/MESA/MESA_handle_logger.h
@@ -0,0 +1,68 @@
+#ifndef MESA_HANDLE__LOGGER_H
+#define MESA_HANDLE__LOGGER_H
+
+/*
+ * runtime_log with handle,
+ * based on runtime_log.
+ * yang wei
+ * create time:2014-03-24
+ * version:20140324
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define RLOG_LV_DEBUG 10
+#define RLOG_LV_INFO 20
+#define RLOG_LV_FATAL 30
+
+
+#define MESA_HANDLE_RUNTIME_LOG(handle, lv, mod, fmt, args...) \
+ MESA_handle_runtime_log((handle), (lv), (mod), "file %s, line %d, " fmt, \
+ __FILE__, __LINE__, ##args)
+
+/*
+ * name: MESA_create_runtime_log_handle
+ * functionality: get runtime_log handle;
+ * params:
+ * file_path: path of log file, like "./log/runtime_log";
+ * level: level of log;
+ * returns:
+ * not NULL, if succeeded;
+ * NULL, if file is not absolute path, or failed to create log file;
+ */
+void *MESA_create_runtime_log_handle(const char *file_path, int level);
+
+/*
+ * name: MESA_handle_runtime_log
+ * functionality: appends log message to runtime log file;
+ * params:
+ * handle:handle of runtime log, which is created by MESA_create_runtime_log_handle;
+ * level: log level, messages with level value smaller the global var
+ * "runtime_log_level" are ignored;
+ * module: name of loggin module;
+ * fmt: format string;
+ * returns:
+ * none;
+ */
+void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...);
+
+/*
+ * name: MESA_destroy_runtime_log_handle
+ * functionality: release runtime log handle memory.
+ * params:
+ * handle: runtime log handle which is going to be released;
+ * returns:
+ * none;
+ */
+void MESA_destroy_runtime_log_handle(void *handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/src/include/MESA/MESA_htable.h b/src/include/MESA/MESA_htable.h
new file mode 100644
index 0000000..54343ee
--- /dev/null
+++ b/src/include/MESA/MESA_htable.h
@@ -0,0 +1,378 @@
+#ifndef __MESA_HTABLE_H_
+#define __MESA_HTABLE_H_
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+
+/*
+ * general purpose hash table implementation.
+ *
+ * xiang hong
+ * 2002-07-28
+ *History:
+ * 2012-03-23 zhengchao add thread safe option and link expire feature;
+ * 2014-01-27 lijia add reentrant feature.
+ */
+
+#define MESA_HASH_DEBUG (0)
+
+#define COMPLEX_KEY_SWITCH (1)
+
+#define ELIMINATE_TYPE_NUM (1)
+#define ELIMINATE_TYPE_TIME (2)
+#define ELIMINATE_TYPE_MANUAL (3) /* delete oldest item by manual */
+
+typedef void * MESA_htable_handle;
+
+
+#define HASH_MALLOC(_n_) malloc(_n_)
+#define HASH_FREE(_p_) free(_p_)
+
+
+#ifndef uchar
+#define uchar unsigned char
+#endif
+#ifndef uint
+#define uint unsigned int
+#endif
+
+/* eliminate algorithm */
+#define HASH_ELIMINATE_ALGO_FIFO (0) /* by default */
+#define HASH_ELIMINATE_ALGO_LRU (1)
+
+/*
+ * hash key compare function prototype, see hash_key_comp().
+ * return value:
+ * 0:key1 and key2 are equal;
+ * other:key1 and key2 not equal.
+ */
+typedef int key_comp_fun_t(const uchar * key1, uint size1, const uchar * key2, uint size2);
+
+/*
+ * hash key->index computing function prototype, see hash_key2index().
+ */
+typedef uint key2index_fun_t(const MESA_htable_handle table, const uchar * key, uint size);
+
+typedef void MESA_htable_data_free_cbfun_t(void *data);
+
+typedef int MESA_htable_expire_notify_cbfun_t(void *data, int eliminate_type);
+
+typedef uchar* MESA_htable_complex_key_dup_cbfun_t(const uchar *key, uint key_size);
+
+typedef void MESA_htable_complex_key_free_cbfun_t(uchar *key, uint key_size);
+
+typedef long hash_cb_fun_t(void *data, const uchar *key, uint size, void *user_arg);
+
+/*
+ * thread_safe: 0:create hash table without thread safe features;
+ * positive:the bigger number has more performance, less collide, but less timeout accuracy.
+ * max number is 1024.
+ * recursive: 0:can't recursive call MESA_htable_xxx series function
+ * 1:can recursive call MESA_htable_xxx series function.
+ * hash_slot_size: how big do you want the table to be, must be 2^N;
+ * max_elem_num: the maximum elements of the HASH-table,0 means infinite;
+ * key_comp: hash key compare function, use default function if NULL;
+ * suggest implement by yourself.
+ * key2index: hash key->index computing function, use default function if NULL;
+ * suggest use MESA_htable built-in function.
+ * data_free: release resources function;
+ * data_expire_with_condition:
+ * if expire_time > 0 and data_expire_with_condition != NULL,
+ * then call this function when an element expired, and give the reason by the 'type'
+ * if expire_time > 0 and data_expire_with_condition is NULL,
+ * eliminate the item immediately;
+ * args:
+ * data: pointer to attached data;
+ * type: item eliminate reason, ELIMINATE_TYPE_NUM or ELIMINATE_TYPE_TIME;
+ * return value of 'data_expire_with_condition':
+ * 1: the item can be eliminated;
+ * 0: the item can't be eliminated, renew the item.
+ * eliminate_type: the algorithm of elimanate a expired element, 0:FIFO; 1:LRU.
+ * expire_time: the element expire time in second, 0 means infinite.
+ */
+typedef struct{
+ unsigned int thread_safe;
+ int recursive;
+ unsigned int hash_slot_size;
+ unsigned int max_elem_num;
+ int eliminate_type;
+ int expire_time;
+ key_comp_fun_t * key_comp;
+ key2index_fun_t * key2index;
+ void (* data_free)(void *data);
+ int (*data_expire_with_condition)(void *data, int eliminate_type);
+#if COMPLEX_KEY_SWITCH
+ uchar* (*complex_key_dup)(const uchar *key, uint key_size);
+ void (* complex_key_free)(uchar *key, uint key_size);
+#endif
+}MESA_htable_create_args_t;
+
+
+/* All of the following functions return value */
+typedef enum{
+ MESA_HTABLE_RET_OK = 0, /* success */
+ MESA_HTABLE_RET_COMMON_ERR = -1, /* general��undefined errors */
+ MESA_HTABLE_RET_ARG_ERR = -2, /* invalid args */
+ MESA_HTABLE_RET_NUM_FULL = -3, /* htable number full */
+ MESA_HTABLE_RET_QEMPTY = -4, /* htable empty */
+ MESA_HTABLE_RET_DUP_ITEM = -5, /* duplicate item */
+ MESA_HTABLE_RET_NOT_FOUND = -6, /* not found item */
+ MESA_HTABLE_RET_LEN_ERR = -7, /* length error */
+ MESA_HTABLE_RET_CANT_GET_LOCK = -8, /* can't get lock in non-block mode */
+ MESA_HTABLE_RET_GET_LOCK_TMOUT = -9, /* get lock timeout */
+}MESA_htable_errno_t;
+
+/*
+ * You should never use this API to create a hash table, use MESA_htable_born() instead.
+ * name: MESA_htable_create
+ * functionality: allocats memory for hash slots, and initialize hash structure;
+ * param:
+ * args: argments set;
+ * args_len: length of argment set;
+ * returns:
+ * NULL : error;
+ * Non-NULL : success;
+ */
+MESA_htable_handle MESA_htable_create(const MESA_htable_create_args_t *args, int args_struct_len);
+
+/*
+ * get total number of HASH element.
+*/
+unsigned int MESA_htable_get_elem_num(const MESA_htable_handle table);
+
+/*
+ * name: MESA_htable_destroy
+ * functionality: cleans up hash structure, frees memory occupied;
+ * param:
+ * table: who is the victim;
+ * func: callback function to clean up data attached to hash items, has higher priority level than MESA_htable_data_free_cbfun_t in initialization.
+
+ * returns:
+ * always returns 0;
+ */
+int MESA_htable_destroy(MESA_htable_handle table, void (* func)(void *));
+
+/*
+ * name: MESA_htable_add
+ * functionality: adds item to table, call hash_expire() if elem_count gets
+ * bigger than threshold_hi, and adjust threshold;
+ * param:
+ * table: to which table do you want to add;
+ * key: what is the label;
+ * size: how long is the label;
+ * data: what data do you want to attach;
+ * returns:
+ * 0: success.
+ * <0: error, refer to MESA_htable_errno_t.
+ */
+int MESA_htable_add(MESA_htable_handle table, const uchar * key, uint size, const void *data);
+#if 0
+/*
+ * name: hash_add_with_expire
+ * functionality: adds item to table, than call hash_expire() on its list
+ * param:
+ * table: to which table do you want to add;
+ * key: what is the label;
+ * size: how long is the label;
+ * data: what data do you want to attach;
+ * returns:
+ * >0 success,return hash elems' linklist size
+ * -1, duplicates found and can't add this one;
+ * -2, memory failure;
+ */
+int MESA_hash_add_with_expire_v3(MESA_htable_inner_t * table, uchar * key, uint size, void * data);
+
+#endif
+
+
+/*
+ * name: MESA_htable_del
+ * functionality: deletes item from table.
+ * param:
+ * table: from which table do you want to delete;
+ * key : what is the label;
+ * size : how long is the label;
+ * func : callback function to clean up data attached to hash items,
+ if this pointer is NULL will call "data_free" in MESA_hash_create(),
+ * returns:
+ * 0 : success;
+ * <0: error, refer to MESA_htable_errno_t.
+ */
+int MESA_htable_del(MESA_htable_handle table, const uchar * key, uint size,
+ void (* func)(void *));
+
+/*
+ * name: MESA_htable_del_oldest_manual
+ * functionality: deletes oldest item from table.
+ * param:
+ * table: from which table do you want to delete;
+ * func : callback function to clean up data attached to hash items,
+ if this pointer is NULL will call "data_free" in MESA_hash_create(),
+ * batch_num: delete oldest items.
+ * returns:
+ * 0, do nothing ;
+ * >0, delete items;
+ */
+int MESA_htable_del_oldest_manual(MESA_htable_handle table, void (* func)(void *), int batch_num);
+
+/*
+ * name: MESA_htable_search
+ * functionality: selects item from table;
+ * param:
+ * table: from which table do you want to select;
+ * key : what is the label;
+ * size : how long is the label;
+ *
+ * return:
+ * not NULL :pointer to attached data;
+ * NULL :not found(thus be careful if you are attaching NULL data on purpose).
+ */
+void *MESA_htable_search(const MESA_htable_handle table, const uchar * key, uint size);
+
+/*
+ * name: MESA_htable_search_cb
+ * functionality: selects item from table, and then call 'cb', reentrant;
+ * in param:
+ * table: from which table do you want to select;
+ * key : what is the label;
+ * size : how long is the label;
+ * cb : call this function when found the attached data;
+ * arg : the argument of "cb" function.
+ * out param:
+ * cb_ret: the return value of the function "cb".
+ * return:
+ * not NULL :pointer to attached data;
+ * NULL :not found(thus be careful if you are attaching NULL data on purpose).
+ */
+void *MESA_htable_search_cb(const MESA_htable_handle table, const uchar * key, uint size,
+ hash_cb_fun_t *cb, void *arg, long *cb_ret);
+
+/*
+ * name: MESA_htable_iterate
+ * functionality: iterates each hash item;
+ * params:
+ * table: what table is to be iterated;
+ * func: what do you want to do to each attached data item;
+ * returns:
+ * 0: iterates all items;
+ * -1: error;
+ */
+int MESA_htable_iterate(MESA_htable_handle table,
+ void (* func)(const uchar * key, uint size, void * data, void *user), void * user);
+
+
+/*
+ * name: MESA_htable_iterate_bytime
+ * functionality: iterates each hash item by your demand;
+ * note:
+ * if 'thread_safe' more than one, this function is not correct.
+ * params:
+ * table: what table is to be iterated;
+ * iterate_type: 1: newest item first; 2: oldest item first;
+ * iterate_cb: what do you want to do to each attached data item;
+ * return value of iterate_cb:
+ * refer to ITERATE_CB_RET_xxx;
+ * returns:
+ * 0: iterates all items;
+ * -1: uncomplete break.
+ * -2: error;
+ */
+#define ITERATE_CB_RET_CONTINUE_FLAG (0) /* default, like MESA_htable_iterate() */
+#define ITERATE_CB_RET_BREAK_FLAG (1<<1) /* break iterate, return from MESA_htable_iterate_bytime() immediately */
+#define ITERATE_CB_RET_DEL_FLAG (1<<2) /* del this item, like but faster than call MESA_htable_del() */
+#define ITERATE_CB_RET_REVERSE_FLAG (1<<3) /* if the item is newest item, it will become the oldest item, and vice versa */
+#define ITERATE_CB_RET_REMOVE_BUT_NOT_FREE (1<<4) /* only remove the item from Hash table, but don't free the attached data, be careful */
+
+#define ITERATE_TYPE_NEWEST_FIRST (1)
+#define ITERATE_TYPE_OLDEST_FIRST (2)
+int MESA_htable_iterate_bytime(MESA_htable_handle table, int iterate_type,
+ int (*iterate_cb)(const uchar * key, uint size, void * data, void *user), void * user);
+
+/*
+ args:
+ print_switch:
+ 0: disable print message;
+ 1: enable print message;
+*/
+void MESA_htable_print_crtl(MESA_htable_handle table, int print_switch);
+
+
+/*
+ Create a htable handle and Alloc memory, and set default option,
+ but can't running before call MESA_htable_mature().
+
+ return value:
+ not NULL: success.
+ NULL : error.
+*/
+MESA_htable_handle MESA_htable_born(void);
+
+/*
+ MESA_htable option definition.
+*/
+enum MESA_htable_opt{
+ MHO_THREAD_SAFE = 0, /* must be int, 1:create hash table with thread safe features, default is 0 */
+ MHO_MUTEX_NUM, /* must be int, valid only if MHO_THREAD_SAFE is not zero, max value is 1024, defalut is 1. the bigger number has more performance and less mutex collide, but less timeout accuracy */
+ MHO_HASH_SLOT_SIZE, /* must be unsigned int, default is 1048576. */
+ MHO_HASH_MAX_ELEMENT_NUM, /* must be unsigned int, defalut is 0, means infinite */
+ MHO_EXPIRE_TIME, /* must be int, defalut is 0, means infinite */
+ MHO_ELIMIMINATE_TYPE, /* must be int, valid only if MHO_EXPIRE_TIME is not zero. HASH_ELIMINATE_ALGO_FIFO or HASH_ELIMINATE_ALGO_LRU, defalut HASH_ELIMINATE_ALGO_FIFO */
+ MHO_CBFUN_KEY_COMPARE, /* must be key_comp_fun_t, hash key compare function, use default function if NULL */
+ MHO_CBFUN_KEY_TO_INDEX, /* must be key2index_fun_t, hash key->index computing function, use default function if NULL */
+ MHO_CBFUN_DATA_FREE, /* must be MESA_htable_data_free_cbfun_t, release resources function */
+ /* data_expire_notify, must be MESA_htable_expire_notify_cbfun_t,
+ * if expire_time > 0 and data_expire_notify != NULL,
+ * then call this function when an element expired, and give the reason by the 'type'
+ * if expire_time > 0 and data_expire_notify is NULL,
+ * eliminate the item immediately;
+ * args:
+ * data: pointer to attached data;
+ * type: item eliminate reason, ELIMINATE_TYPE_NUM or ELIMINATE_TYPE_TIME;
+ * return value of 'data_expire_with_condition':
+ * 1: the item can be eliminated;
+ * 0: the item can't be eliminated, renew the item.
+ */
+ MHO_CBFUN_DATA_EXPIRE_NOTIFY,
+ MHO_CBFUN_COMPLEX_KEY_DUP, /* must be MESA_htable_complex_key_dup_cbfun_t, if key store in a complex struct, caller must be implement this duplicate function. */
+ MHO_CBFUN_COMPLEX_KEY_FREE, /* must be MESA_htable_complex_key_free_cbfun_t, if key store in a complex struct, caller must be implement this duplicate function. */
+ MHO_AUTO_UPDATE_TIME, /* must be int, create a background thread used to update current_time instead of time(NULL). 1:enable; 0:disable; default value is 0; */
+ MHO_SCREEN_PRINT_CTRL, /* must be int, 1:enable screen print; 0:disable screen print; default is 1. */
+ __MHO_MAX_VAL, /* caller can't use this definition, it's value maybe changed in next version!! */
+};
+
+
+/*
+ to set features of specified MESA_htable handle.
+ opt_type: option type, refer to enum MESA_htable_opt;
+ opt_val : option value, depend on opt type;
+ opt_len : opt_val size, depend on opt type;
+
+ return value:
+ 0 :success;
+ <0:error;
+*/
+int MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, void *opt_val, int opt_len);
+
+/*
+ Construct htable and ready to running.
+
+ return value:
+ 0 : success;
+ <0: error.
+*/
+int MESA_htable_mature(MESA_htable_handle table);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIB_HASH_H_INCLUDED_ */
+
+
diff --git a/src/include/MESA/MESA_list_queue.h b/src/include/MESA/MESA_list_queue.h
new file mode 100644
index 0000000..08ce32b
--- /dev/null
+++ b/src/include/MESA/MESA_list_queue.h
@@ -0,0 +1,115 @@
+#ifndef _MESA_LIST_QUEUE_H_
+#define _MESA_LIST_QUEUE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ MESA_list �����棬
+ 1-�����̰߳�ȫ����;
+ 2-�����ڲ��ṹ, ����ȫ���ӿڸ����;
+ 3-�������������й����ڵ�ṹ��ʹ�ø�����;
+*/
+
+#define MESA_LIST_QUEUE_VERSION_MACRO (20160308)
+extern const unsigned int MESA_LIST_QUEUE_VERSION_INT;
+
+#define MESA_LIST_OP_PLACE_HEAD (0x1)
+#define MESA_LIST_OP_PLACE_TAIL (0x2)
+
+#define MESA_list_GET (0x1)
+#define MESA_list_JOIN (0x2)
+
+#define MESA_list_BOLCK (0x4)
+#define MESA_list_NONBOLCK (0x8)
+
+#define MESA_list_JOIN_BLOCK (MESA_list_JOIN|MESA_list_BOLCK)
+#define MESA_list_JOIN_NONBLOCK (MESA_list_JOIN|MESA_list_NONBOLCK)
+#define MESA_list_GET_BLOCK (MESA_list_GET|MESA_list_BOLCK)
+#define MESA_list_GET_NONBLOCK (MESA_list_GET|MESA_list_NONBOLCK)
+
+typedef void * MESA_lqueue_head;
+typedef int (* MESA_lqueue_cb_t)(void *data, long data_len, void *arg);
+
+/* All of the following functions return value */
+typedef enum{
+ MESA_QUEUE_RET_OK = 0, /* success */
+ MESA_QUEUE_RET_COMMON_ERR = -1, /* general��undefined errors */
+ MESA_QUEUE_RET_ARG_ERR = -2, /* invalid args */
+ MESA_QUEUE_RET_NUM_FULL = -3, /* queue number full */
+ MESA_QUEUE_RET_MEM_FULL = -4, /* queue memory full */
+ MESA_QUEUE_RET_QEMPTY = -5, /* queue empty */
+ MESA_QUEUE_RET_LEN_ERR = -6, /* length error */
+ MESA_QUEUE_RET_CANT_GET_LOCK = -7, /* can't get lock in non-block mode */
+ MESA_QUEUE_RET_GET_LOCK_TMOUT = -8, /* get lock timeout */
+}MESA_queue_errno_t;
+
+/*
+ args description:
+ [IN]
+ thread_safe : 1:create thread safe queue; 0:without thread safe insurance.
+ max_item_num: maximum queue items of the queue, 0 means infinity.
+*/
+MESA_lqueue_head MESA_lqueue_create(int thread_safe, long max_item_num);
+
+/*
+ attention:
+ The follow two functions is get some value of queue in a moment,
+ however, the value you got is not exactly,
+ because it's maybe changed immediately by other thread when this functions is return.
+*/
+long MESA_lqueue_get_mem_used(MESA_lqueue_head head);
+long MESA_lqueue_get_count(MESA_lqueue_head head);
+
+
+/*
+ args description:
+ [IN]:
+ lq_head : the handler of MESA_lqueue.
+
+ [OUT]:
+ data : receive buffer.
+
+ [IN && OUT]:
+ data_len:
+ is value-result argument, like "addrlen of recvfrom(2)",
+ the caller should initialize the size of the 'data',
+ will modified on return to indicate the actual size of the queue item.
+
+*/
+int MESA_lqueue_read_head(MESA_lqueue_head lq_head, void *data, long *data_len);
+int MESA_lqueue_get_head(MESA_lqueue_head lqhead, void *data, long *data_len);
+
+/*
+ if return value of "cb" is 0, the behaviour is like MESA_lqueue_read_head(),
+ else if return value of "cb" is not 0, the behaviour is like MESA_lqueue_get_head().
+*/
+int MESA_lqueue_detect_get_head(MESA_lqueue_head lq_head, MESA_lqueue_cb_t cb, void *data, long *data_len, void *cb_arg);
+int MESA_lqueue_get_tail(MESA_lqueue_head lq_head, void *data, long *data_len);
+
+int MESA_lqueue_join_head(MESA_lqueue_head lq_head, const void *data, long data_len);
+int MESA_lqueue_join_tail(MESA_lqueue_head lq_head, const void *data, long data_len);
+
+
+/* these functions features same with above no "try",
+ except shall return immediately, in other word is "Non-block mode"!
+ */
+int MESA_lqueue_try_read_head(MESA_lqueue_head lq_head, void *data, long *data_len);
+int MESA_lqueue_try_get_head(MESA_lqueue_head lq_head, void *data, long *data_len);
+int MESA_lqueue_try_get_tail(MESA_lqueue_head lq_head, void *data, long *data_len);
+int MESA_lqueue_try_join_head(MESA_lqueue_head lq_head, const void *data, long data_len);
+int MESA_lqueue_try_join_tail(MESA_lqueue_head lq_head, const void *data, long data_len);
+
+
+void MESA_lqueue_destroy(MESA_lqueue_head head, MESA_lqueue_cb_t cb, void *cb_arg);
+
+const char *MESA_lqueue_strerror(MESA_queue_errno_t error_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/include/MESA/MESA_prof_load.h b/src/include/MESA/MESA_prof_load.h
new file mode 100644
index 0000000..84c5deb
--- /dev/null
+++ b/src/include/MESA/MESA_prof_load.h
@@ -0,0 +1,179 @@
+#ifndef SLIB_LOADPROF_H
+#define SLIB_LOADPROF_H
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// Read in specified integer value
+//
+// Return:
+// 0 : success
+// < 0 : error, val is set to default
+int MESA_load_profile_int_def(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ int *val, // [OUT] returned value
+ const int dval); // [IN] default value
+
+
+
+// Read in specified integer value
+//
+// Return:
+// 0 : success
+// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error
+// -2 : error ,the val if out of range
+int MESA_load_profile_int_nodef(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ int *val); // [OUT] returned value
+
+
+
+
+// Read in specified unsigned integer value
+//
+// Return:
+// 0 : success
+// < 0 : error, val is set to default
+int MESA_load_profile_uint_def(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ unsigned int *val, // [OUT] returned value
+ const unsigned int dval); // [IN] default value
+
+
+
+// Read in specified unsigned integer value
+//
+// Return:
+// 0 : success
+// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error
+// -2 : error ,the val if out of range
+int MESA_load_profile_uint_nodef(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ unsigned int *val); // [OUT] returned value
+
+
+
+// Read in specified short integer value
+//
+// Return:
+// 0 : success
+// < 0 : error, val is set to default
+int MESA_load_profile_short_def(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ short *val, // [OUT] returned value
+ const short dval); // [IN] default value
+
+
+
+// Read in specified short integer value
+//
+// Return:
+// 0 : success
+// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error
+// -2 : error ,the val if out of range
+int MESA_load_profile_short_nodef(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ short *val); // [OUT] returned value
+
+
+
+// Read in specified string value,
+// if value string is too long to return, extra chars truncated.
+// prefix/postfix space chars cutted,
+// space chars: ' ', '\t' '\n' '\r'
+//
+// Return:
+// >= 0 : length of val
+// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error
+
+int MESA_load_profile_string_nodef(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ char *str, // [OUT] returned string
+ const size_t size); // [IN] buffer size(bytes)
+
+
+
+// Read in specified string value,
+// if value string is too long to return, extra chars truncated.
+// prefix/postfix space chars cutted,
+// space chars: ' ', '\t' '\n' '\r'
+//
+// Return:
+// >= 0 : length of val
+// < 0 : error, str is set to default
+int MESA_load_profile_string_def(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ char *str, // [OUT] returned string
+ const size_t size, // [IN] buffer size(bytes)
+ const char *dstr); // [IN] default string
+
+
+
+//read ips from config file
+//return :
+// >=0 : success,return the number of ip read from file successfully
+// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error
+// -2 : error,invalid ip
+
+#if 0
+int MESA_load_profile_ipset(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ const size_t size, // [IN] the size of memory ips point,it must equel or greater than ip_num*sizeof(unsigned int)
+ unsigned int *ipset); // [OUT] return ipset network bytes order
+
+// Write the a int into specified position of the config file,the position is decided by section and key
+// Return:
+// >= 0 : success
+// -1 : failed to write profile,maybe fopen failed, or malloc failed
+int MESA_write_profile_int(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ const int value); // [IN] the integer need write
+
+// Write the a float into specified position of the config file,the position is decided by section and key
+// Return:
+// >= 0 : success
+// -1 : failed to write profile,maybe fopen failed, or malloc failed
+int MESA_write_profile_float(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ const float value); // [IN] the float need write
+
+// Write the a string into specified position of the config file,the position is decided by section and key
+// Return:
+// >= 0 : success
+// -1 : failed to write profile,maybe fopen failed, or malloc failed
+int MESA_write_profile_string(
+ const char *file, // [IN] initialization file path
+ const char *section, // [IN] section name in initialization file
+ const char *key, // [IN] keyword name in initialization file
+ const char *value); // [IN] the string need write
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef SLIB_LOADPROF_H */
diff --git a/src/include/MESA/Maat_rule.h b/src/include/MESA/Maat_rule.h
new file mode 100644
index 0000000..93e499f
--- /dev/null
+++ b/src/include/MESA/Maat_rule.h
@@ -0,0 +1,239 @@
+
+/*
+*****************Maat Network Flow Rule Manage Framework********
+* Maat is the Goddess of truth and justice in ancient Egyptian concept.
+* Her feather was the measure that determined whether the souls (considered
+* to reside in the heart) of the departed would reach the paradise of afterlife
+* successfully.
+* Author: [email protected],MESA
+* Version 2015-11-09 digest scan
+* NOTE: MUST compile with G++
+* All right reserved by Institute of Infomation Engineering,Chinese Academic of Science 2014~2018
+*********************************************************
+*/
+#ifndef H_MAAT_RULE_H_INCLUDE
+#define H_MAAT_RULE_H_INCLUDE
+#ifndef __cplusplus
+#error("This file should be compiled with C++ compiler")
+#endif
+#include "stream.h"
+enum MAAT_CHARSET
+{
+ CHARSET_NONE=0,
+ CHARSET_GBK,
+ CHARSET_BIG5,
+ CHARSET_UNICODE,
+ CHARSET_UTF8, // 4
+ CHARSET_BIN, //5
+ CHARSET_UNICODE_ASCII_ESC, // Unicode Escape format, prefix backslash-u hex, e.g. "\u627;"
+ CHARSET_UNICODE_ASCII_ALIGNED,//Unicode Escape format, prefix backslash-u with 4 bytes aligned, e.g. "\u0627"
+ CHARSET_UNICODE_NCR_DEC, //SGML Numeric character reference,decimal base, e.g. "&#1575;"
+ CHARSET_UNICODE_NCR_HEX, //SGML Numeric character reference,hexdecimal base, e.g. "&#x627;"
+ CHARSET_URL_ENCODE_GB2312, //URL encode with GB2312, e.g. the chinese word "china" was encoded to %D6%D0%B9%FA
+ CHARSET_URL_ENCODE_UTF8 //11, URL encode with UTF8,e.g. the chinese word "china" was encoded to %E4%B8%AD%E5%9B%BD
+};
+enum MAAT_ACTION
+{
+ MAAT_ACTION_BLOCK=0,
+ MAAT_ACTION_MONIT,
+ MAAT_ACTION_WHITE
+};
+enum MAAT_POS_TYPE
+{
+ MAAT_POSTYPE_EXPR=0,
+ MAAT_POSTYPE_REGEX
+};
+typedef void* scan_status_t;
+typedef void* stream_para_t;
+typedef void* Maat_feather_t;
+
+
+#define MAX_SERVICE_DEFINE_LEN 128
+struct Maat_rule_t
+{
+ int config_id;
+ int service_id;
+ char do_log;
+ char do_blacklist;
+ char action;
+ char resevered;
+ int serv_def_len;
+ char service_defined[MAX_SERVICE_DEFINE_LEN];
+};
+#define MAAT_RULE_UPDATE_TYPE_FULL 1
+#define MAAT_RULE_UPDATE_TYPE_INC 2
+typedef void Maat_start_callback_t(int update_type,void* u_para);
+typedef void Maat_update_callback_t(int table_id,const char* table_line,void* u_para);
+typedef void Maat_finish_callback_t(void* u_para);
+
+
+
+
+
+//--------------------HITTING DETAIL DESCRIPTION BEGIN
+
+#define MAAT_MAX_HIT_RULE_NUM 8
+#define MAAT_MAX_EXPR_ITEM_NUM 8
+#define MAAT_MAX_HIT_POS_NUM 8
+#define MAAT_MAX_REGEX_GROUP_NUM 8
+
+//NOTE position buffer as hitting_regex_pos and hit_pos,are ONLY valid before next scan or Maat_stream_scan_string_end
+struct regex_pos_t
+{
+ int group_num;
+ int hitting_regex_len;
+ const char* hitting_regex_pos;
+ int grouping_len[MAAT_MAX_REGEX_GROUP_NUM];
+ const char* grouping_pos[MAAT_MAX_REGEX_GROUP_NUM];
+};
+struct str_pos_t
+{
+ int hit_len;
+ const char* hit_pos;
+};
+struct sub_item_pos_t
+{
+ enum MAAT_POS_TYPE ruletype;
+ int hit_cnt;
+ union
+ {
+ struct regex_pos_t regex_pos[MAAT_MAX_HIT_POS_NUM];
+ struct str_pos_t substr_pos[MAAT_MAX_HIT_POS_NUM];
+ };
+};
+
+struct Maat_region_pos_t
+{
+
+ int region_id;
+ int sub_item_num;
+ struct sub_item_pos_t sub_item_pos[MAAT_MAX_EXPR_ITEM_NUM];
+};
+
+struct Maat_hit_detail_t
+{
+ int config_id;//set <0 if half hit;
+ int hit_region_cnt;
+ struct Maat_region_pos_t region_pos[MAAT_MAX_HIT_RULE_NUM];
+};
+//--------------------HITTING DETAIL DESCRIPTION END
+
+//Abondon interface ,left for compatible.
+Maat_feather_t Maat_summon_feather(int max_thread_num,
+ const char* table_info_path,
+ const char* ful_cfg_dir,
+ const char* inc_cfg_dir,
+ void*logger);//MESA_handle_logger
+//Abondon interface ,left for compatible.
+Maat_feather_t Maat_summon_feather_json(int max_thread_num,
+ const char* table_info_path,
+ const char* json_rule,
+ void* logger);
+
+Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* logger);
+int Maat_initiate_feather(Maat_feather_t feather);
+
+enum MAAT_INIT_OPT
+{
+ MAAT_OPT_SCANDIR_INTERVAL_MS=1, //VALUE is interger, SIZE=sizeof(int). DEFAULT:1,000 milliseconds.
+ MAAT_OPT_EFFECT_INVERVAL_MS, //VALUE is interger, SIZE=sizeof(int). DEFAULT:60,000 milliseconds.
+ MAAT_OPT_FULL_CFG_DIR, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1.DEFAULT: no default.
+ MAAT_OPT_INC_CFG_DIR, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1.DEFAULT: no default.
+ MAAT_OPT_JSON_FILE_PATH, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1.DEFAULT: no default.
+ MAAT_OPT_STAT_ON, //VALUE is NULL,SIZE is 0. MAAT_OPT_STAT_FILE_PATH must be set. Default: stat OFF.
+ MAAT_OPT_PERF_ON, //VALUE is NULL,SIZE is 0. MAAT_OPT_STAT_FILE_PATH must be set. Default: stat OFF.
+ MAAT_OPT_STAT_FILE_PATH, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: no default.
+ MAAT_OPT_SCAN_DETAIL, //VALUE is interger *, SIZE=sizeof(int). 0: not return any detail;1: return hit pos, not include regex grouping;
+ // 2 return hit pos and regex grouping pos;DEFAULT:0
+ MAAT_OPT_INSTANCE_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1, no more than 11 bytes.DEFAULT: MAAT_$tableinfo_path$.
+ MAAT_OPT_DECRYPT_KEY, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT.
+ MAAT_OPT_REDIS_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT.
+ MAAT_OPT_REDIS_PORT, //VALUE is a unsigned short or a signed int, host order, SIZE= sizeof(unsigned short) or sizeof(int). No DEFAULT.
+ MAAT_OPT_REDIS_INDEX, //VALUE is interger *, 0~15, SIZE=sizeof(int). DEFAULT: 0.
+ MAAT_OPT_CMD_AUTO_NUMBERING, //VALUE is a interger *, 1 or 0, SIZE=sizeof(int). DEFAULT: 1.
+ MAAT_OPT_DEFERRED_LOAD, //VALUE is NULL,SIZE is 0. Default: Deffered initialization OFF.
+ MAAT_OPT_CUMULATIVE_UPDATE_OFF, //VALUE is NULL,SIZE is 0. Default: CUMMULATIVE UPDATE ON.
+ MAAT_OPT_LOAD_VERSION_FROM, //VALUE is a long long, SIZE=sizeof(long long). Default: Load the Latest. Only valid in redis mode, and maybe failed for too old.
+ //This option also disables background update.
+ MAAT_OPT_ENABLE_UPDATE //VALUE is interger, SIZE=sizeof(int). 1: Enabled, 0:Disabled. DEFAULT: Backgroud update is enabled. Runtime setting is allowed.
+};
+//return -1 if failed, return 0 on success;
+int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const void* value,int size);
+enum MAAT_STATE_OPT
+{
+ MAAT_STATE_VERSION=1, //Get current maat version. VALUE is long long, SIZE=sizeof(long long).
+ MAAT_STATE_LAST_UPDATING_TABLE //Query at Maat_finish_callback_t to determine whether this table is the last one to update. VALUE is interger, SIZE=sizeof(int), 1:yes, 0: no
+};
+int Maat_read_state(Maat_feather_t feather, enum MAAT_STATE_OPT type, void* value, int size);
+
+void Maat_burn_feather(Maat_feather_t feather);
+
+//return table_id(>=0) if success,otherwise return -1;
+int Maat_table_register(Maat_feather_t feather,const char* table_name);
+//return 1 if success,otherwise return -1 incase invalid table_id or registed function number exceed 32;
+int Maat_table_callback_register(Maat_feather_t feather,short table_id,
+ Maat_start_callback_t *start,//MAAT_RULE_UPDATE_TYPE_*,u_para
+ Maat_update_callback_t *update,//table line ,u_para
+ Maat_finish_callback_t *finish,//u_para
+ void* u_para);
+
+enum MAAT_SCAN_OPT
+{
+ MAAT_SET_SCAN_DISTRICT=1, //VALUE is a const char*,SIZE= strlen(string).DEFAULT: no default.
+ MAAT_SET_SCAN_LAST_REGION //VALUE is NULL, SIZE=0. This option indicates that the follow scan is the last region of current scan cobination.
+};
+//return 0 if success, return -1 when failed;
+int Maat_set_scan_status(Maat_feather_t feather,scan_status_t* mid,enum MAAT_SCAN_OPT type,const void* value,int size);
+
+//Return hit rule number, return -1 when error occurs,return -2 when hit current region
+//mid MUST set to NULL before fist call
+int Maat_scan_intval(Maat_feather_t feather,int table_id
+ ,unsigned int intval
+ ,struct Maat_rule_t*result,int rule_num
+ ,scan_status_t *mid,int thread_num);
+int Maat_scan_addr(Maat_feather_t feather,int table_id
+ ,struct ipaddr* addr
+ ,struct Maat_rule_t*result,int rule_num
+ ,scan_status_t *mid,int thread_num);
+int Maat_scan_proto_addr(Maat_feather_t feather,int table_id
+ ,struct ipaddr* addr,unsigned short int proto
+ ,struct Maat_rule_t*result,int rule_num
+ ,scan_status_t *mid,int thread_num);
+int Maat_full_scan_string(Maat_feather_t feather,int table_id
+ ,enum MAAT_CHARSET charset,const char* data,int data_len
+ ,struct Maat_rule_t*result,int* found_pos,int rule_num
+ ,scan_status_t* mid,int thread_num);
+//hite_detail could be NULL if unconcern
+int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id
+ ,enum MAAT_CHARSET charset,const char* data,int data_len
+ ,struct Maat_rule_t*result,int rule_num,struct Maat_hit_detail_t *hit_detail,int detail_num
+ ,int* detail_ret,scan_status_t* mid,int thread_num);
+
+stream_para_t Maat_stream_scan_string_start(Maat_feather_t feather,int table_id,int thread_num);
+int Maat_stream_scan_string(stream_para_t* stream_para
+ ,enum MAAT_CHARSET charset,const char* data,int data_len
+ ,struct Maat_rule_t*result,int* found_pos,int rule_num
+ ,scan_status_t* mid);
+//hited_detail could be NULL if unconcern
+int Maat_stream_scan_string_detail(stream_para_t* stream_para
+ ,enum MAAT_CHARSET charset,const char* data,int data_len
+ ,struct Maat_rule_t*result,int rule_num,struct Maat_hit_detail_t *hit_detail,int detail_num
+ ,int* detail_ret,scan_status_t* mid);
+void Maat_stream_scan_string_end(stream_para_t* stream_para);
+
+stream_para_t Maat_stream_scan_digest_start(Maat_feather_t feather,int table_id,unsigned long long total_len,int thread_num);
+int Maat_stream_scan_digest(stream_para_t* stream_para
+ ,const char* data,int data_len,unsigned long long offset
+ ,struct Maat_rule_t*result,int rule_num
+ ,scan_status_t* mid);
+void Maat_stream_scan_digest_end(stream_para_t* stream_para);
+
+int Maat_similar_scan_string(Maat_feather_t feather,int table_id
+ ,const char* data,int data_len
+ ,struct Maat_rule_t*result,int rule_num
+ ,scan_status_t* mid,int thread_num);
+
+void Maat_clean_status(scan_status_t* mid);
+
+#endif // H_MAAT_RULE_H_INCLUDE
+
diff --git a/src/include/MESA/asmis_log.h b/src/include/MESA/asmis_log.h
new file mode 100644
index 0000000..b04dc89
--- /dev/null
+++ b/src/include/MESA/asmis_log.h
@@ -0,0 +1,73 @@
+#ifndef __ASMIS_LOG_H
+#define __ASMIS_LOG_H
+#ifndef __cplusplus
+#error("This file should be compiled with C++ compiler")
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+//#include <support/thread_safe.h>
+
+#define ASMIS_KEY 0x01
+#define ASMIS_ALARM 0x02
+#define ASMIS_OTHER 0x03
+
+#define ASMIS_LOGMSG_TIMEOUT 300 //second
+#define ASMIS_LOGMSG_LENGTH 40000 //bytes
+
+//ϵͳʹ�ö˿���Ϣ�ṹ��
+struct info_port_used {
+ unsigned short nPort;
+ unsigned char nProtocolType;
+ unsigned char nPortType;
+ char sPortDesc[128];
+};
+
+//ϵͳʵʱ������Ϣ�ṹ��
+struct info_rtd_flow {
+ char sValType[32];
+ char sBDType[32];
+ time_t nRTTS;
+ int nDuration;
+ unsigned long long nValue;
+};
+
+//ϵͳ���Ը�����Ϣ�ṹ��
+struct info_policy_update {
+ char sName[128];
+ char sDesc[256];
+ time_t nUpdateTime;
+ char sVersion[33];
+ int nTotal;
+ int nNew;
+ int nDelete;
+ int nUpdate;
+ int nSize;
+};
+
+//NetLog��ʼ��
+void* asmis_log_Init(const char *pProcName);
+//�Ǽdz���汾��Ϣ
+int asmis_log_AppVer(void* netlog_handle,const char *pVersionTime, const char *pVersionNO, const char *pVersionDesc);
+//ϵͳ������־
+int asmis_log_LogMsg(void* netlog_handle,const char *pMsg, const char *pNo, int nAlarmType);
+//�Ǽ�ϵͳʹ�ö˿�
+int asmis_log_PortUsed(void* netlog_handle,struct info_port_used *info, int nPort);
+//�Ǽ�ϵͳʵʱ������Ϣ
+int asmis_log_RtdFlow(void* netlog_handle,time_t nStartTime, int nDuration, struct info_rtd_flow *info, int nFlow);
+//�Ǽ�ϵͳ��ʼ����
+int asmis_log_RunStart(void* netlog_handle,int nContiRun);
+//�Ǽ�ϵͳֹͣ��Ϣ
+int asmis_log_RunStop(void* netlog_handle,int nContiRun);
+//������Ϣ
+int asmis_log_HeartBeat(void* netlog_handle,const char *pMsg);
+//���Ը�����Ϣ
+int asmis_log_Policy(void* netlog_handle,struct info_policy_update *info, int nPolicy);
+
+#endif
diff --git a/src/include/MESA/field_stat2.h b/src/include/MESA/field_stat2.h
new file mode 100644
index 0000000..7dbf5a5
--- /dev/null
+++ b/src/include/MESA/field_stat2.h
@@ -0,0 +1,66 @@
+#ifndef H_SCREEN_STAT2_H_INCLUDE
+#define H_SCREEN_STAT2_H_INCLUDE
+#include <stdio.h>
+
+#ifndef __cplusplus
+#error("This file should be compiled with C++ compiler")
+#endif
+
+enum field_dsp_style_t
+{
+ FS_STYLE_FIELD=0,
+ FS_STYLE_COLUMN,
+ FS_STYLE_LINE,
+ FS_STYLE_STATUS
+};
+enum field_calc_algo
+{
+ FS_CALC_CURRENT=0,
+ FS_CALC_SPEED
+};
+enum field_op
+{
+ FS_OP_ADD=1,
+ FS_OP_SET
+};
+
+
+typedef void* screen_stat_handle_t;
+
+enum FS_option
+{
+ OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout.
+ PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE.
+ STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds.
+ PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1.
+ CREATE_THREAD, //VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function,
+ //and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0.
+ ID_INVISBLE, //value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one.
+ FLUSH_BY_DATE, //value is 1(ture) or 0(false),SIZE=4,DEFAULT: Do not flush by date.
+ APP_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT is "?".
+ STATS_SERVER_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT.
+ STATS_SERVER_PORT, //VALUE is a unsigned short, host order, SIZE= sizeof(unsigned short). No DEFAULT.
+};
+
+//Always success.
+screen_stat_handle_t FS_create_handle(void);
+
+int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size);
+void FS_start(screen_stat_handle_t handle);
+void FS_stop(screen_stat_handle_t* handle);
+
+//return field_id/line_id/column_id greater than zero if success,return an interger less than zero if failed.
+//should NOT include '\n','|' or ':' in the parameter name.
+int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name);
+
+//numerator_id and denominator_id must be column/field/status style.
+//scaling: negative value: zoom in; positive value: zoom out;
+int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name);
+
+//id: when id's type is FIELD , column_id is ignore.
+int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value);
+
+void FS_passive_output(screen_stat_handle_t handle);
+
+#endif
+
diff --git a/src/include/grule_for_view.h b/src/include/grule_for_view.h
new file mode 100644
index 0000000..8e1a4c9
--- /dev/null
+++ b/src/include/grule_for_view.h
@@ -0,0 +1,425 @@
+#ifndef __GRULE_H
+#define __GRULE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/ip.h>
+
+typedef void * grule_hdl_t;
+//typedef void * rule_item_t;
+
+
+/*
+* ע��:
+* ���е�ַ��ṹʹ��������(�����ģʽ)��������ʹ��������
+*/
+
+#if __BYTE_ORDER != __LITTLE_ENDIAN
+#error "machine is not little-endian"
+#endif
+
+
+/*#define GRULE_TYPE_SIP 1
+#define GRULE_TYPE_SIP_DIP 5
+#define GRULE_TYPE_SIP_SPORT 9
+#define GRULE_TYPE_SIP_PROTO 257
+#define GRULE_TYPE_SIP_SPORT_PROTO 273
+#define GRULE_TYPE_SIP_DPORT 65
+#define GRULE_TYPE_SIP_DPORT_PROTO 321
+#define GRULE_TYPE_SIP_DIP_PROTO 261
+#define GRULE_TYPE_DIP 4
+#define GRULE_TYPE_DIP_DPORT 68
+#define GRULE_TYPE_DIP_DPORT_PROTO 324
+#define GRULE_TYPE_DIP_PROTO 260
+#define GRULE_TYPE_DIP_SPORT_PROTO 276
+*/
+
+typedef union{
+ struct{
+ uint16_t sip_flag:1;
+ uint16_t sipmsk_flag:1;
+ uint16_t dip_flag:1;
+ uint16_t dipmsk_flag:1;
+ uint16_t sport_flag:1;
+ uint16_t spmsk_flag:1;
+ uint16_t dport_flag:1;
+ uint16_t dpmsk_flag:1;
+ uint16_t proto_flag:1;
+ uint16_t pmsk_flag:1;
+ uint16_t vlan_flag:1;
+ uint16_t ddir_flag:1;
+ uint16_t hit_flag:1;
+ uint16_t resv:4; // resv must be zero
+ };
+ uint16_t grule_type;
+}grule_type_t;
+
+
+
+
+typedef uint32_t ip4_addr_t;
+typedef uint16_t port_t;
+typedef union{
+ unsigned long ip6_l[2];
+ unsigned int ip6_i[4];
+ unsigned char ip6_c[16];
+}ip6_addr_t;
+
+
+typedef struct{
+ ip4_addr_t sip;
+ ip4_addr_t dip;
+ port_t sport;
+ port_t dport;
+ uint8_t proto;
+}simple4_rule_t;
+
+typedef struct{
+ ip6_addr_t sip;
+ ip6_addr_t dip;
+ port_t sport;
+ port_t dport;
+ uint8_t proto;
+}simple6_rule_t;
+
+typedef struct{
+ ip4_addr_t sip;
+ ip4_addr_t sip_mask;
+ ip4_addr_t dip;
+ ip4_addr_t dip_mask;
+ port_t sport;
+ port_t sport_mask;
+ port_t dport;
+ port_t dport_mask;
+ uint8_t proto;
+ uint8_t proto_mask;
+}mask4_rule_t;
+
+
+typedef struct{
+ ip6_addr_t sip;
+ ip6_addr_t sip_mask;
+ ip6_addr_t dip;
+ ip6_addr_t dip_mask;
+ port_t sport;
+ port_t sport_mask;
+ port_t dport;
+ port_t dport_mask;
+ uint8_t proto;
+ uint8_t proto_mask;
+}mask6_rule_t;
+
+
+#define GRULE_BIG_TYPE_SIMPLE4 1
+#define GRULE_BIG_TYPE_SIMPLE6 2
+#define GRULE_BIG_TYPE_MASK4 3
+#define GRULE_BIG_TYPE_MASK6 4
+
+#define GRULE_ACTION_ADD 1
+#define GRULE_ACTION_DEL 0
+
+
+
+#define RULE_VERSION_BASE 1
+#define RULE_VERSION_TUPLE6 2
+
+typedef struct{
+ uint64_t rule_id;// rule uniq id
+ uint32_t srv_type; // rule service type
+ uint32_t rule_scope; // rule scope, such as all of carrier, China unicom
+ uint16_t big_type; // GRULE_BIG_TYPE_SIMPLE4, GRULE_BIG_TYPE_SIMPLE6, GRULE_BIG_TYPE_MASK4,
+ uint16_t durable; // rule is durable
+ uint16_t action; // add or delete
+ grule_type_t rule_type;
+ union{
+ simple4_rule_t s4;
+ simple6_rule_t s6;
+ mask4_rule_t m4;
+ mask6_rule_t m6;
+ };
+}grule_t;
+
+
+typedef struct{
+ //uint64_t rule_id;
+ grule_t rule;
+ uint32_t vlan;
+ uint32_t vlan_mask;
+}grule2_t;
+
+
+typedef struct {
+ void *rvec_base;
+ size_t rvec_size;
+ uint32_t rule_ver;
+}rulevec_t;
+
+
+
+#define GRULE_SOL_PROTO 1
+
+#define GRULE_TYPE_AUTH 1
+#define GRULE_TYPE_NONBLOCK 2
+
+#define GRULE_OK 0
+#define GRULE_ERR -1
+
+#define GRULE_ERRNO_AGAIN 99
+#define GRULE_ERRNO_BAD_RULE 100
+#define GRULE_ERRNO_BAD_OPT 101
+#define GRULE_ERRNO_BAD_CONNECTION 102
+#define GRULE_ERRNO_AUTH 103
+
+#define GRULE_RESP_OK 0
+#define GRULE_RESP_WHITELIST 1
+
+
+typedef struct{
+ //uint64_t rule_id;
+ uint32_t result;
+}grule_result_t;
+
+
+
+/*
+* return 0, if rule is ok. otherwise rule is bad.
+*/
+int grule_check_rule(const grule_t * rule);
+
+
+/*#define GRULE_APP_STATUS_AUTHING 1 // authenticaing, it cannot send data;
+#define GRULE_APP_STATUS_AUTH_ERROR 2
+//#define GRULE_APP_STATUS_AUTH_SUCC
+#define GRULE_APP_STATUS_CONNECTED 3 // connected, send all durable rules;
+#define GRULE_APP_STATUS_ACTIVE 4 // active, send one rule;
+#define GRULE_APP_STATUS_CLOSE 5 // close.
+*/
+
+
+#define GRULE_APP_STATUS_IDLE 1
+#define GRULE_APP_STATUS_CONNECTED 2
+#define GRULE_APP_STATUS_ACTIVE 3
+
+
+//int grule_restart(grule_hdl_t hdl);
+
+
+/*
+get app status
+ return -1 if it failed, otherwise return status
+*/
+int grule_app_status(grule_hdl_t hdl);
+
+/*
+ init grule handle
+*/
+grule_hdl_t grule_open();
+
+/*
+ get option value of rule handle, including rule handle, tcp.
+ return 0 if it succeded, otherwise -1. grule_errno() indicates the detailed error.
+*/
+int grule_opt_get(grule_hdl_t hdl, int level, int type, void * opt, size_t opt_size);
+
+
+/*
+* set option of rule handle
+return 0 if it succeded, otherwise -1. grule_errno() indicates the detailed error.
+
+*/
+int grule_opt_set(grule_hdl_t hdl, int level, int type, const void * opt, size_t opt_size);
+
+/*
+* connect server;
+return 0 if it succeded, otherwise -1. grule_errno() indicates the detailed error.
+
+*/
+int grule_connect(grule_hdl_t hdl, const char * addr);
+
+/*
+* send rules, flags=0
+* return > 1 if it succeded, 0: connecting state, try again, <0 rule error
+
+*/
+int grule_send(grule_hdl_t hdl, grule_t *rules, size_t rule_num, int flags);
+
+
+int grule_sendmsg(grule_hdl_t hdl, rulevec_t *vec, size_t vec_size, int flags);
+
+int grule_mask2flexible(const grule_t * src, grule_t * dst);
+
+
+/*
+* recieve result;flags=0
+* return 0 if it succeded, otherwise -1. grule_errno() indicates the detailed error.
+*/
+int grule_recv(grule_hdl_t hdl, grule_result_t *rst, size_t rst_num, int flags);
+
+
+/*
+ * int grule_cache_size(grule_hdl_t hdl);
+ * */
+int grule_cache_size(grule_hdl_t hdl);
+
+/*
+* get error info of result;
+*/
+const char * grule_bad_results_str(grule_result_t *rst);
+
+const char * grule_error_str(int err_no);
+
+int grule_errno(grule_hdl_t hdl);
+
+
+#define GRULE_SERVER_FIRST_CONNECT 1
+#define GRULE_SERVER_NONFIRST_CONNECT 0
+int grule_app_firstconnect_status(grule_hdl_t client);
+
+/*
+* release hdl
+*/
+int grule_close(grule_hdl_t hdl);
+
+void parse_rule(grule_t * rule);
+
+char * parse_rule_str(grule_t * rule, char * buf, size_t *size);
+char * parse_rule_str_full(grule_t * rule, char * buf, size_t *size);
+char * parse_rule2_str_full(grule2_t * rule, char * buf, size_t *size);
+//usage
+
+#if 0
+
+#define CCC_MAX_SIZE 16
+int grule_service()
+{
+ grule_hdl_t handle;
+ const char *ccc_list[CCC_MAX_SIZE]; //it should be inited.
+ size_t ccc_num = 8;
+ size_t ccc_index = 0;
+ int state;
+ uint8_t auth_data[8]; // it should be inited
+ int ret;
+ size_t auth_err_num;
+ size_t i;
+
+ grule_t rule_list[16];
+ grule_result_t rst_list[16];
+ uint64_t rule_num;
+
+ #define SERVICE_STATE_IDLE 1
+ #define SERVICE_STATE_FIRSTCONNECT 2
+ #define SERVICE_STATE_CONNECTED 3
+ //#define SERVICE_STATE_
+
+ state = SERVICE_STATE_IDLE;
+ auth_err_num = 0;
+ handle = NULL;
+ while(1){
+
+ switch(state){
+ case SERVICE_STATE_IDLE:
+ handle = grule_open();
+ if(handle == NULL){
+ fprintf(stderr, "grule lib error\n");
+ abort();
+ }
+ grule_opt_set(handle, GRULE_SOL_PROTO, GRULE_TYPE_AUTH, auth_data, sizeof(auth_data));
+ ret = grule_connect(handle, ccc_list[ccc_index]);
+ ccc_index = (ccc_index + 1) % ccc_num;
+ if(ret == 0){
+ state = SERVICE_STATE_FIRSTCONNECT;
+ auth_err_num = 0;
+ continue;
+ }
+ if(grule_errno(handle) == GRULE_ERRNO_AUTH){
+ auth_err_num++;
+ if(auth_err_num >= ccc_num){
+ fprintf(stderr, "auth error\n");
+ abort();
+ }
+ // stop the program if trying many times
+ }else{
+ fprintf(stderr, "connect error: %s\n", grule_error_str(grule_errno(handle)));
+ }
+ goto _error;
+ break;
+ case SERVICE_STATE_FIRSTCONNECT:
+ // if having durable rules, send all of them.
+ state = SERVICE_STATE_CONNECTED;
+ break;
+ //break;
+ case SERVICE_STATE_CONNECTED:
+ //
+ while(1){
+ // has rule?????
+
+ memset(rule_list, 0, sizeof(rule_list));
+ // init
+ // set rule;
+ // sending
+ ret = grule_send(handle, rule_list, rule_num, 0);
+ if(ret != rule_num){
+ fprintf(stderr, "sending error: %s\n", grule_error_str(grule_errno(handle)));
+ goto _error;
+ }
+
+ ret = grule_recv(handle, rst_list, rule_num, 0);
+ if(ret != rule_num){
+ fprintf(stderr, "recv error: %s\n", grule_error_str(grule_errno(handle)));
+ goto _error;
+ }
+
+ for(i = 0; i < rule_num; i++){
+ if(rst_list[i].result != GRULE_RESP_OK && rst_list[i].result != GRULE_RESP_WHITELIST){ // rule is wrong.
+ fprintf(stderr, "rulerror: %s\n", grule_bad_results_str(&rst_list[i]));
+ abort();// fatal error.
+ }
+ }
+ }
+ break;
+ default:
+ fprintf(stderr, "bad state: %d\n", state);
+ abort();
+ break;
+ }
+ _noerror:
+ continue;
+ _error:
+ if(handle != NULL){
+ grule_close(handle);
+ }
+ sleep(2);
+ state = SERVICE_STATE_IDLE;
+
+ }
+}
+
+#endif
+
+
+#define RULE_SIP 0x0001
+#define RULE_SIPMASK 0x0002
+#define RULE_DIP 0x0004
+#define RULE_DIPMASK 0x0008
+#define RULE_SPORT 0x0010
+#define RULE_SPMASK 0x0020
+#define RULE_DPORT 0x0040
+#define RULE_DPMASK 0x0080
+#define RULE_PROTO 0x0100
+#define RULE_PMASK 0x0200
+#define RULE_VLAN 0x0400
+//#define RULE_VLANMASK 0x0800
+#define RULE_HIT 0x1000
+#define RULE_DDIR 0x0800
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/src/lib/libmaatframe.a b/src/lib/libmaatframe.a
new file mode 100644
index 0000000..081a35e
--- /dev/null
+++ b/src/lib/libmaatframe.a
Binary files differ
diff --git a/src/load_table_info.hpp b/src/load_table_info.hpp
new file mode 100644
index 0000000..184c6eb
--- /dev/null
+++ b/src/load_table_info.hpp
@@ -0,0 +1,107 @@
+#ifndef __LOAD_TABLE_INFO_COMMON_H__
+#define __LOAD_TABLE_INFO_COMMON_H__
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace std;
+
+template <class table_info_type>
+class LoadTableInfo{
+private:
+ char table_path[256];
+ char *get_filecont_line(char *line_content, int32_t cont_size, FILE *fp);
+ int32_t (*fill_cb)(char *line_content, table_info_type *table, int32_t table_index);
+
+public:
+ LoadTableInfo(const char *table_confile, int32_t (*fill_table_info_cb)(char *line_content, table_info_type *table, int32_t table_index))
+ {
+ snprintf(table_path, 256, "%s", table_confile);
+ fill_cb = fill_table_info_cb;
+ }
+ virtual ~LoadTableInfo()
+ {
+ }
+
+ int load_table_info(table_info_type **table_lists, int *num);
+};
+
+template <class table_info_type>
+char *LoadTableInfo<table_info_type>::get_filecont_line(char *line_content, int32_t cont_size, FILE *fp)
+{
+ int line_len;
+ char *content=NULL;
+
+ while(NULL!=fgets(line_content, cont_size, fp) && !feof(fp))
+ {
+ line_len = strlen(line_content);
+ if((line_len+1 == cont_size) || (line_content[line_len-1] != '\n'))
+ {
+ printf("This line data is too long!\n");
+ assert(0);
+ return NULL;
+ }
+ content = line_content;
+
+ while(line_len>0 && (*content==' ' || *content=='\t'))
+ {
+ content++;
+ line_len--;
+ }
+ if(line_len==0 || *content=='#' || *content=='\r' || *content=='\n')
+ {
+ continue;
+ }
+
+ return content;
+ }
+
+ return NULL;
+}
+
+template <class table_info_type>
+int LoadTableInfo<table_info_type>::load_table_info(table_info_type **table_lists, int *num)
+{
+#define MALLOC_TABLE_ARRAY_NUM 8
+ table_info_type *maat_list;
+ char *line_content, *cur_content;
+ FILE *fp_user;
+ int maat_num=0, maat_max_num=MALLOC_TABLE_ARRAY_NUM;
+
+ fp_user = fopen(table_path, "r");
+ if(fp_user==NULL)
+ {
+ assert(0);
+ return -1;
+ }
+ line_content = (char *)calloc(1, 4096);
+ maat_list = (table_info_type *)calloc(1, maat_max_num*sizeof(table_info_type));
+
+ while((cur_content=get_filecont_line(line_content, 4096, fp_user))!=NULL)
+ {
+ if(maat_num >= maat_max_num)
+ {
+ maat_max_num += MALLOC_TABLE_ARRAY_NUM;
+ maat_list = (table_info_type *)realloc(maat_list, maat_max_num*sizeof(table_info_type));
+ memset(maat_list+maat_num, 0, MALLOC_TABLE_ARRAY_NUM*sizeof(table_info_type));
+ }
+
+ if((*fill_cb)(cur_content, &maat_list[maat_num], maat_num))
+ {
+ fclose(fp_user);
+ free(line_content);
+ return -1;
+ }
+ maat_num += 1;
+ }
+ *num = maat_num;
+ *table_lists = maat_list;
+
+ fclose(fp_user);
+ free(line_content);
+ return 0;
+}
+
+#endif
+
diff --git a/src/pg_valve_c3.cpp b/src/pg_valve_c3.cpp
new file mode 100644
index 0000000..4eb764a
--- /dev/null
+++ b/src/pg_valve_c3.cpp
@@ -0,0 +1,448 @@
+#include <stdio.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <assert.h>
+#include <signal.h>
+
+#include "pg_valve_c3.h"
+#include "pg_valve_main.h"
+#include "check_ip_legal.h"
+
+extern pgvavle_global_info_t g_pgvalve_info;
+pg_grule_handle_t g_grule_handle;
+
+int authdata_hex2mem(const char *source, int srclen, char* dest)
+{
+ int i,j;
+ unsigned char c,h4bit,l4bit;
+
+ if( NULL == source || NULL==dest || srclen<=0 )
+ {
+ return -1;
+ }
+
+ for(i=0,j=0; i<srclen; )
+ {
+ c = source[i];
+ if(c >= '0' && c <= '9')
+ h4bit = c - '0';
+ else if(c >= 'A' && c <= 'F')
+ h4bit = c - 'A' + 10;
+ else if(c >= 'a' && c <= 'f')
+ h4bit = c - 'a' + 10;
+ else
+ {
+ if(i == srclen -1)//the last c is 0a
+ {
+ return j;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ ++i;
+
+ if(i>=srclen)
+ {
+ return -1;
+ }
+
+ c = source[i];
+ if(c >= '0' && c <= '9')
+ l4bit = c - '0';
+ else if(c >= 'A' && c <= 'F')
+ l4bit = c - 'A' + 10;
+ else if(c >= 'a' && c <= 'f')
+ l4bit = c - 'a' + 10;
+ else
+ {
+ return -1;
+ }
+ dest[j]= (h4bit<<4)|l4bit;
+
+ j++;
+ i++;
+ }
+ dest[j] = '\0';
+
+ return j;
+}
+
+const char *get_disp_status_str(int disp_status)
+{
+ switch(disp_status)
+ {
+ case DISP_SUCC: return "succ";
+ case DISP_FAIL_C3: return "fail_c3";
+ case DISP_FAIL_C3_CHECK:return "fail_c3_check";
+ case DISP_LIMIT: return "fail_reach_limit";
+ case DISP_RETRY: return "fail_wait_full";
+ default: return "unknown";
+ }
+}
+
+void write_grule_log(const char *table_name, grule_t &grule, int disp_status, int errcode)
+{
+ char sip[128], dip[128], smask[128], dmask[128];
+ u_int16_t sport, dport;
+
+ switch(grule.big_type)
+ {
+ case GRULE_BIG_TYPE_SIMPLE4:
+ inet_ntop(AF_INET, &grule.s4.sip, sip, 128);
+ inet_ntop(AF_INET, &grule.s4.dip, dip, 128);
+ sport = grule.s4.sport;
+ dport = grule.s4.dport;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_dispatch_%s: %s, simple4, rule_id: 0x%lx-%lu, double_dir: %s, action: %s, rule_type: 0x%hx, serv_type: %d, tuple4: %s_%d>%s_%d(%s)",
+ get_disp_status_str(disp_status), table_name, grule.rule_id, grule.rule_id, grule.rule_type.ddir_flag?"yes":"no", grule.action==GRULE_ACTION_ADD?"ADD":"DEL", grule.rule_type, grule.srv_type, sip, ntohs(sport), dip, ntohs(dport), errcode?grule_error_str(errcode):"");
+ break;
+
+ case GRULE_BIG_TYPE_SIMPLE6:
+ inet_ntop(AF_INET6, &grule.s6.sip.ip6_c, sip, 128);
+ inet_ntop(AF_INET6, &grule.s6.dip.ip6_c, dip, 128);
+ sport = grule.s6.sport;
+ dport = grule.s6.dport;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_dispatch_%s: %s, simple6, rule_id: 0x%lx-%lu, double_dir: %s, action: %s, rule_type: 0x%hx, serv_type: %d, tuple4: %s_%d>%s_%d(%s)",
+ get_disp_status_str(disp_status), table_name, grule.rule_id, grule.rule_id, grule.rule_type.ddir_flag?"yes":"no", grule.action==GRULE_ACTION_ADD?"ADD":"DEL", grule.rule_type, grule.srv_type, sip, ntohs(sport), dip, ntohs(dport), errcode?grule_error_str(errcode):"");
+ break;
+
+ case GRULE_BIG_TYPE_MASK4:
+ inet_ntop(AF_INET, &grule.m4.sip, sip, 128);
+ inet_ntop(AF_INET, &grule.m4.dip, dip, 128);
+ inet_ntop(AF_INET, &grule.m4.sip_mask, smask, 128);
+ inet_ntop(AF_INET, &grule.m4.dip_mask, dmask, 128);
+ sport = grule.m4.sport;
+ dport = grule.m4.dport;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_dispatch_%s: %s, mask4, rule_id: 0x%lx-%lu, double_dir: %s, action: %s, rule_type: 0x%hx, serv_type: %d, tuple4: %s_%d>%s_%d, mask4: %s_%d>%s_%d(%s)",
+ get_disp_status_str(disp_status), table_name, grule.rule_id, grule.rule_id, grule.rule_type.ddir_flag?"yes":"no", grule.action==GRULE_ACTION_ADD?"ADD":"DEL", grule.rule_type, grule.srv_type, sip, ntohs(sport), dip, ntohs(dport), smask, ntohs(grule.m4.sport_mask), dmask, ntohs(grule.m4.dport_mask), errcode?grule_error_str(errcode):"");
+ break;
+
+ case GRULE_BIG_TYPE_MASK6:
+ inet_ntop(AF_INET6, &grule.m6.sip.ip6_c, sip, 128);
+ inet_ntop(AF_INET6, &grule.m6.dip.ip6_c, dip, 128);
+ inet_ntop(AF_INET6, &grule.m6.sip_mask.ip6_c, smask, 128);
+ inet_ntop(AF_INET6, &grule.m6.dip_mask.ip6_c, dmask, 128);
+ sport = grule.m6.sport;
+ dport = grule.m6.dport;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_dispatch_%s: %s, mask6, rule_id: 0x%lx-%lu, double_dir: %s, action: %s, rule_type: 0x%hx, serv_type: %d, tuple4: %s_%d>%s_%d, mask4: %s_%d>%s_%d(%s)",
+ get_disp_status_str(disp_status), table_name, grule.rule_id, grule.rule_id, grule.rule_type.ddir_flag?"yes":"no", grule.action==GRULE_ACTION_ADD?"ADD":"DEL", grule.rule_type, grule.srv_type, sip, ntohs(sport), dip, ntohs(dport), smask, ntohs(grule.m6.sport_mask), dmask, ntohs(grule.m6.dport_mask), errcode?grule_error_str(errcode):"");
+ break;
+ }
+}
+
+int mask4_ip_is_valid(u_int32_t ip, u_int32_t ipmask)
+{
+ if((ip&0x000000FF)==0 || ipmask<0x000000FF || (ipmask&0x000000FF)<0x000000FF)
+ {
+ return 0;
+ }
+ return 1;
+}
+
+SSCANF_ERROR_NO_t _wrap_grule_check(grule_t *grule)
+{
+ grule_type_t rule_type;
+ grule_t tmpgrule;
+
+ rule_type = grule->rule_type;
+ rule_type.ddir_flag = 0;
+ switch(rule_type.grule_type)
+ {
+ case DIP:
+ case DIP_PROTO:
+ case DIP_DPORT_PROTO:
+ case DIP_SPORT_PROTO:
+ case DIP_SPORT_DPORT_PROTO:
+ case SIP:
+ case SIP_PROTO:
+ case SIP_DPORT_PROTO:
+ case SIP_SPORT_PROTO:
+ case SIP_SPORT_DPORT_PROTO:
+ case SIP_DIP:
+ case SIP_DIP_PROTO:
+ case SIP_DIP_DPORT_PROTO:
+ case SIP_DIP_SPORT_PROTO:
+ case SIP_DIP_SPORT_DPORT_PROTO:
+ case DIP_MDIP:
+ case DIP_MDIP_PROTO_MPROTO:
+ case DIP_MDIP_DPORT_MDPORT_PROTO_MPROTO:
+ case DIP_MDIP_SPORT_MSPORT_PROTO_MPROTO:
+ case DIP_MDIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO:
+ case SIP_MSIP:
+ case SIP_MSIP_PROTO_MPROTO:
+ case SIP_MSIP_DPORT_MDPORT_PROTO_MPROTO:
+ case SIP_MSIP_SPORT_MSPORT_PROTO_MPROTO:
+ case SIP_MSIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO:
+ case SIP_MSIP_DIP_MDIP:
+ case SIP_MSIP_DIP_MDIP_PROTO_MPROTO:
+ case SIP_MSIP_DIP_MDIP_DPORT_MDPORT_PROTO_MPROTO:
+ case SIP_MSIP_DIP_MDIP_SPORT_MSPORT_PROTO_MPROTO:
+ case SIP_MSIP_DIP_MDIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO:
+ break;
+
+ default: return SSCANF_ERROR_TUPLE;
+ }
+
+ switch(grule->big_type)
+ {
+ case GRULE_BIG_TYPE_SIMPLE4:
+ if((grule->rule_type.sip_flag && (grule->s4.sip&0x000000FF)==0) || (grule->rule_type.dip_flag && (grule->s4.dip&0x000000FF)==0))
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ break;
+ case GRULE_BIG_TYPE_SIMPLE6:
+ if((grule->rule_type.sip_flag && ipv6_valid(grule->s6.sip.ip6_c)!=IPV6_OK) || (grule->rule_type.dip_flag && ipv6_valid(grule->s6.dip.ip6_c)!=IPV6_OK))
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ break;
+ case GRULE_BIG_TYPE_MASK4:
+ tmpgrule = *grule;
+ if(tmpgrule.rule_type.sipmsk_flag)
+ {
+ tmpgrule.m4.sip &= tmpgrule.m4.sip_mask; //��������
+ if(!mask4_ip_is_valid(tmpgrule.m4.sip, tmpgrule.m4.sip_mask))
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ if(tmpgrule.rule_type.spmsk_flag)
+ {
+ tmpgrule.m4.sport &= tmpgrule.m4.sport_mask;
+ if(tmpgrule.m4.sport == 0)
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ if(tmpgrule.rule_type.dipmsk_flag)
+ {
+ tmpgrule.m4.dip &= tmpgrule.m4.dip_mask;
+ if(!mask4_ip_is_valid(tmpgrule.m4.dip, tmpgrule.m4.dip_mask))
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ if(tmpgrule.rule_type.dpmsk_flag)
+ {
+ tmpgrule.m4.dport &= tmpgrule.m4.dport_mask;
+ if(tmpgrule.m4.dport == 0)
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ grule_mask2flexible(&tmpgrule, grule);
+ break;
+ case GRULE_BIG_TYPE_MASK6:
+ tmpgrule = *grule;
+ if(tmpgrule.rule_type.spmsk_flag)
+ {
+ tmpgrule.m6.sport &= tmpgrule.m6.sport_mask;
+ if(tmpgrule.m6.sport == 0)
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ if(tmpgrule.rule_type.dpmsk_flag)
+ {
+ tmpgrule.m6.dport &= tmpgrule.m6.dport_mask;
+ if(tmpgrule.m6.dport == 0)
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ if(tmpgrule.rule_type.sipmsk_flag)
+ {
+ tmpgrule.m6.sip.ip6_l[0] &= tmpgrule.m6.sip_mask.ip6_l[0];
+ tmpgrule.m6.sip.ip6_l[1] &= tmpgrule.m6.sip_mask.ip6_l[1];
+ if(ipv6m_valid(tmpgrule.m6.sip.ip6_c, tmpgrule.m6.sip_mask.ip6_c) != IPV6_OK)
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ if(tmpgrule.rule_type.dipmsk_flag)
+ {
+ tmpgrule.m6.dip.ip6_l[0] &= tmpgrule.m6.dip_mask.ip6_l[0];
+ tmpgrule.m6.dip.ip6_l[1] &= tmpgrule.m6.dip_mask.ip6_l[1];
+ if(ipv6m_valid(tmpgrule.m6.dip.ip6_c, tmpgrule.m6.dip_mask.ip6_c) != IPV6_OK)
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ }
+ grule_mask2flexible(&tmpgrule, grule);
+ if(grule->big_type == GRULE_BIG_TYPE_SIMPLE6 && ((grule->rule_type.sip_flag && ipv6_valid(grule->s6.sip.ip6_c)!=IPV6_OK)
+ || (grule->rule_type.dip_flag && ipv6_valid(grule->s6.dip.ip6_c)!=IPV6_OK)))
+ {
+ return SSCANF_ERROR_RULE;
+ }
+ break;
+ default: break;
+ }
+ return SSCANF_OK;
+}
+
+int do_dispatch_config_to_c3(grule_t &grule, int *errcode)
+{
+ int ret = DISP_SUCC;
+
+ while(grule_app_status(g_grule_handle.grule_handle) == GRULE_APP_STATUS_IDLE)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "grule_app_status GRULE_APP_STATUS_IDLE, retry 2 seconds later.");
+ sleep(2);
+ }
+
+ pthread_mutex_lock(&g_grule_handle.mutex_lock);
+ if(g_grule_handle.first_connect)
+ {
+ pthread_mutex_unlock(&g_grule_handle.mutex_lock);
+ return DISP_RETRY;
+ }
+
+ if(grule_app_firstconnect_status(g_grule_handle.grule_handle) == GRULE_SERVER_FIRST_CONNECT)
+ {
+ g_grule_handle.first_connect = 1;
+ if(pthread_kill(g_grule_handle.signal_thid, SIGUSR1))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "--------------Attention: pthread_kill failed, restart now.--------------");
+ exit(10);
+ }
+ pthread_mutex_unlock(&g_grule_handle.mutex_lock);
+ return DISP_RETRY;
+ }
+
+ if(grule_send(g_grule_handle.grule_handle, &grule, 1, 0) != 1)
+ {
+ *errcode = grule_errno(g_grule_handle.grule_handle);
+ pthread_mutex_unlock(&g_grule_handle.mutex_lock);
+ return DISP_FAIL_C3;
+ }
+ //int num = grule_cache_size(g_grule_handle.grule_handle);
+
+ pthread_mutex_unlock(&g_grule_handle.mutex_lock);
+
+ return ret;
+}
+
+int wrap_dispatch_config_to_c3(const char *table_name, int service_id, int table_id, grule_t &grule)
+{
+ int ret, errcode=0;
+
+ ret = do_dispatch_config_to_c3(grule, &errcode);
+ if(ret != DISP_SUCC)
+ {
+ pz_trans_statistic_count(service_id, table_id, 1, STAT_FIELD_DISP_FAIL);
+ }
+ else
+ {
+ pz_trans_statistic_count(service_id, table_id, 1, STAT_FIELD_DISP_SUCC);
+ }
+
+ write_grule_log(table_name, grule, ret, errcode);
+ return ret;
+}
+
+STAT_SERVICE_TYPE_t update_grule_status(int32_t &status, int disp_ret, int action)
+{
+ if(disp_ret != DISP_SUCC)
+ {
+ if(disp_ret == DISP_RETRY && action==GRULE_ACTION_DEL)
+ {
+ status = 0; //�����ؽ�ʱ����ɾ�������ã�������·�״̬
+ }
+ return STAT_SERVICE_NONE;
+ }
+
+ if((action==GRULE_ACTION_ADD) && status==0)
+ {
+ status = 1;
+ return STAT_SERVICE_ADD;
+ }
+ else if((action==GRULE_ACTION_DEL) && status!=0)
+ {
+ status = 0;
+ return STAT_SERVICE_DEL;
+ }
+ return STAT_SERVICE_NONE;
+}
+
+//���޸��·���״̬��������ע����¸�״̬
+int dispatch_config_to_c3(const char *table_name, int service_id, int table_id, one_config_hnode_t &config_node)
+{
+ int ret;
+ STAT_SERVICE_TYPE_t type;
+
+ //ȫ�µ��������òż�����ޣ�config_node.disp_statusΪ0��ʾȫ��ADD���û���DEL�Ѿ�ɾ���ɹ�������
+ //���⶯̬��������DEL�����
+ if(g_pgvalve_info.service_limit_sw && config_node.disp_status==0 && (config_node.grule.action==GRULE_ACTION_DEL || service_grule_reach_limit(config_node.grule.srv_type)))
+ {
+ write_grule_log(table_name, config_node.grule, DISP_LIMIT, 0);
+ pz_trans_statistic_count(service_id, table_id, 1, STAT_FIELD_DISP_LIMIT);
+ return DISP_LIMIT;
+ }
+
+ ret = wrap_dispatch_config_to_c3(table_name, service_id, table_id, config_node.grule);
+ type = update_grule_status(config_node.disp_status, ret, config_node.grule.action);
+ if(type != STAT_SERVICE_NONE)
+ {
+ service_grule_statistic_count(config_node.grule.srv_type, config_node.grule.rule_type.ddir_flag?2:1, type); //˫�����ռ�������ռ�
+ }
+ return ret;
+}
+
+void clear_c3_first_status(void)
+{
+ pthread_mutex_lock(&g_grule_handle.mutex_lock);
+ g_grule_handle.first_connect = 0;
+ pthread_mutex_unlock(&g_grule_handle.mutex_lock);
+}
+
+bool global_init_grule_handle(const char *auth_data_str, int len, const char *ccc_list, pthread_t signal_thid)
+{
+ char authdata[16];
+ pthread_mutexattr_t attr;
+ int attr_type;
+
+ if(C3CLIENTLEN != authdata_hex2mem(auth_data_str, len, authdata))
+ {
+ assert(0);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "C3_AUTH_DATA format error.");
+ return false;
+ }
+ g_grule_handle.first_connect = 0;
+ g_grule_handle.grule_handle = grule_open();
+ if(g_grule_handle.grule_handle == NULL)
+ {
+ return false;
+ }
+ if(grule_opt_set(g_grule_handle.grule_handle, GRULE_SOL_PROTO, GRULE_TYPE_AUTH, authdata, C3CLIENTLEN))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "grule_opt_set GRULE_TYPE_AUTH error.");
+ return false;
+ }
+ if(grule_connect(g_grule_handle.grule_handle, ccc_list))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "grule_connect %s error: %s.", ccc_list, grule_error_str(grule_errno(g_grule_handle.grule_handle)));
+ return false;
+ }
+
+ while(grule_app_status(g_grule_handle.grule_handle) == GRULE_APP_STATUS_IDLE)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "grule_app_status GRULE_APP_STATUS_IDLE, retry 2 seconds later.");
+ sleep(2);
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "grule real connect %s success.", ccc_list);
+ grule_app_firstconnect_status(g_grule_handle.grule_handle); //�״�����ʱ���Ե�һ������״̬
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_gettype(&attr, &attr_type);
+ attr_type |= PTHREAD_MUTEX_RECURSIVE_NP; /* can be recursive call */
+ pthread_mutexattr_settype(&attr, attr_type);
+ if(pthread_mutex_init(&g_grule_handle.mutex_lock, &attr))
+ {
+ return false;
+ }
+ g_grule_handle.signal_thid = signal_thid;
+ return true;
+}
+
diff --git a/src/pg_valve_c3.h b/src/pg_valve_c3.h
new file mode 100644
index 0000000..0a32332
--- /dev/null
+++ b/src/pg_valve_c3.h
@@ -0,0 +1,72 @@
+#ifndef __PANGU_VALVE_C3_H__
+#define __PANGU_VALVE_C3_H__
+
+#include "grule_for_view.h"
+#include "pg_valve_tools.h"
+#include "pg_valve_stat.h"
+
+#define G_DIR_DOUBLE 0
+#define G_DIR_C2S 1
+#define G_DIR_S2C 2
+
+#define C3CLIENTLEN 8
+
+#define DISP_SUCC 10
+#define DISP_FAIL_C3 -20
+#define DISP_FAIL_C3_CHECK -30
+#define DISP_LIMIT -40
+#define DISP_RETRY -50
+
+//һ��ֱ����Ч����KEY: CONFIG_STRING
+typedef struct __one_config_hnode
+{
+ grule_t grule;
+ int32_t disp_status; //���������·���״̬���·��ɹ�����1�����ɹ���δ�·�ʱ��0��STATUS_BIT_ORIGINAL/STATUS_BIT_REVERSE
+}one_config_hnode_t;
+
+int dispatch_config_to_c3(const char *table_name, int service_id, int table_id, one_config_hnode_t &config_node);
+
+typedef struct __pg_grule_handle
+{
+ grule_hdl_t grule_handle;
+ pthread_mutex_t mutex_lock;
+ pthread_t signal_thid;
+ int first_connect;
+}pg_grule_handle_t;
+
+void clear_c3_first_status(void);
+bool global_init_grule_handle(const char *auth_data_str, int len, const char *ccc_list, pthread_t signal_thid);
+
+#define DIP 0x4
+#define DIP_PROTO 0x104
+#define DIP_DPORT_PROTO 0x144
+#define DIP_SPORT_PROTO 0x114
+#define DIP_SPORT_DPORT_PROTO 0x154
+#define SIP 0x1
+#define SIP_PROTO 0x101
+#define SIP_DPORT_PROTO 0x141
+#define SIP_SPORT_PROTO 0x111
+#define SIP_SPORT_DPORT_PROTO 0x151
+#define SIP_DIP 0x5
+#define SIP_DIP_PROTO 0x105
+#define SIP_DIP_DPORT_PROTO 0x145
+#define SIP_DIP_SPORT_PROTO 0x115
+#define SIP_DIP_SPORT_DPORT_PROTO 0x155
+#define DIP_MDIP 0xc
+#define DIP_MDIP_PROTO_MPROTO 0x30c
+#define DIP_MDIP_DPORT_MDPORT_PROTO_MPROTO 0x3cc
+#define DIP_MDIP_SPORT_MSPORT_PROTO_MPROTO 0x33c
+#define DIP_MDIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO 0x3fc
+#define SIP_MSIP 0x3
+#define SIP_MSIP_PROTO_MPROTO 0x303
+#define SIP_MSIP_DPORT_MDPORT_PROTO_MPROTO 0x3c3
+#define SIP_MSIP_SPORT_MSPORT_PROTO_MPROTO 0x333
+#define SIP_MSIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO 0x3f3
+#define SIP_MSIP_DIP_MDIP 0xf
+#define SIP_MSIP_DIP_MDIP_PROTO_MPROTO 0x30f
+#define SIP_MSIP_DIP_MDIP_DPORT_MDPORT_PROTO_MPROTO 0x3cf
+#define SIP_MSIP_DIP_MDIP_SPORT_MSPORT_PROTO_MPROTO 0x33f
+#define SIP_MSIP_DIP_MDIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO 0x3ff
+
+#endif
+
diff --git a/src/pg_valve_consul.cpp b/src/pg_valve_consul.cpp
new file mode 100644
index 0000000..df2bd6c
--- /dev/null
+++ b/src/pg_valve_consul.cpp
@@ -0,0 +1,193 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <curl/curl.h>
+
+#include <MESA/MESA_handle_logger.h>
+
+#include "cJSON.h"
+#include "pg_valve_consul.h"
+#include "pg_valve_tools.h"
+
+CURLSH *curl_shared_handle;
+
+static size_t write_response_to_string_cb(void *ptr, size_t size, size_t count, void *buff)
+{
+ struct easy_string* estr=(struct easy_string*)buff;
+ if(estr->size-estr->len<size*count+1)
+ {
+ estr->size+=size*count*2+1;
+ estr->buff=(char*)realloc(estr->buff,estr->size);
+ }
+ memcpy(estr->buff+estr->len,ptr,size*count);
+ estr->len+=size*count;
+ estr->buff[estr->len]='\0';
+ return size*count;
+}
+
+static size_t read_body_to_send_cb(void *ptr, size_t size, size_t count, void *buff)
+{
+ size_t len;
+ struct easy_string *request = (struct easy_string *)buff;
+
+ if(size==0 || count==0 || request->len>=request->size)
+ {
+ return 0;
+ }
+
+ len = request->size - request->len; //ʣ����ϴ��ij���
+ if(len > size * count)
+ {
+ len = size * count;
+ }
+
+ memcpy(ptr, request->buff + request->len, len);
+ request->len += len;
+ return len;
+}
+
+bool http_put_request(const char* url, const char *body, int timeout_s, struct easy_string* response)
+{
+ CURL *curl;
+ CURLcode res1, res2;
+ long res_code;
+ struct easy_string request;
+
+ curl = curl_easy_init();
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout_s);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1L);
+ curl_easy_setopt(curl, CURLOPT_MAXREDIRS,3);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response_to_string_cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
+ curl_easy_setopt(curl, CURLOPT_SHARE, curl_shared_handle);
+ curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 600L); //10���ӲŽ���һ��DNS����
+
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
+ if(body != NULL)
+ {
+ request.size = strlen(body); //�ܴ�С
+ request.len = 0; //���ϴ�����
+ request.buff = (char *)body; //����
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, request.size);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_body_to_send_cb);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &request);
+ }
+
+ res1 = curl_easy_perform(curl);
+ res2 = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code);
+ curl_easy_cleanup(curl);
+ if(res1==CURLE_OK && res2==CURLE_OK && res_code==200)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool consul_renew_session(const char *session_id, int timeout_s)
+{
+ char reg_url[156];
+ struct easy_string response;
+ cJSON *session, *json;
+
+ snprintf(reg_url, 256, "http://localhost:8500/v1/session/renew/%s", session_id);
+ memset(&response,0,sizeof(response));
+ if(!http_put_request(reg_url, NULL, timeout_s, &response))
+ {
+ free(response.buff);
+ return false;
+ }
+
+ if(NULL == (session=cJSON_Parse(response.buff)))
+ {
+ free(response.buff);
+ return false;
+ }
+ free(response.buff);
+ if(NULL == (json=cJSON_GetObjectItem(session->child, "ID")))
+ {
+ cJSON_Delete(session);
+ return false;
+ }
+ if(strcmp(session_id, json->valuestring))
+ {
+ cJSON_Delete(session);
+ return false;
+ }
+
+ cJSON_Delete(session);
+ return true;
+}
+
+bool consul_create_session(int lock_delay_s, int ttl_s, char *session_id, int size, void *runlog)
+{
+ cJSON *session, *json;
+ char tmpbuf[128], *body;
+ const char* reg_url="http://localhost:8500/v1/session/create";
+ struct easy_string response;
+
+ curl_global_init(CURL_GLOBAL_NOTHING);
+ curl_shared_handle = curl_share_init();
+ curl_share_setopt(curl_shared_handle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
+
+ session = cJSON_CreateObject();
+ sprintf(tmpbuf, "%us", lock_delay_s);
+ cJSON_AddStringToObject(session, "LockDelay", tmpbuf);
+ sprintf(tmpbuf, "%us", ttl_s);
+ cJSON_AddStringToObject(session, "TTL", tmpbuf);
+ cJSON_AddStringToObject(session, "Name", "pg_valve_session");
+ cJSON_AddStringToObject(session, "Behavior", "release");
+
+ body = cJSON_Print(session);
+ cJSON_Delete(session);
+ memset(&response,0,sizeof(response));
+ while(!http_put_request(reg_url, body, 5, &response))
+ {
+ free(response.buff);
+ memset(&response,0,sizeof(response)); //��Ҫ��գ������һ��ʧ�ܺ󣬵ڶ��ε�ʱ����Ұָ��
+ MESA_HANDLE_RUNTIME_LOGV2(runlog, RLOG_LV_FATAL, "CONSUL", "consul_create_session failed, retry after 10 seconds.");
+ sleep(10);
+ }
+ free(body);
+
+ if(NULL == (session=cJSON_Parse(response.buff)))
+ {
+ free(response.buff);
+ return false;
+ }
+ free(response.buff);
+ if(NULL == (json=cJSON_GetObjectItem(session, "ID")))
+ {
+ cJSON_Delete(session);
+ return false;
+ }
+
+ snprintf(session_id, size, "%s", json->valuestring);
+ cJSON_Delete(session);
+ return true;
+}
+
+bool consul_try_get_lock(const char *session_id, const char *key, const char *value, int timeout_s)
+{
+ char reg_url[156];
+ struct easy_string response;
+
+ snprintf(reg_url, 256, "http://localhost:8500/v1/kv/%s?acquire=%s", key, session_id);
+ memset(&response,0,sizeof(response));
+ if(!http_put_request(reg_url, value, timeout_s, &response))
+ {
+ free(response.buff);
+ return false;
+ }
+
+ if(!strcasecmp(response.buff, "true"))
+ {
+ free(response.buff);
+ return true;
+ }
+ free(response.buff);
+ return false;
+}
+
diff --git a/src/pg_valve_consul.h b/src/pg_valve_consul.h
new file mode 100644
index 0000000..13c3c13
--- /dev/null
+++ b/src/pg_valve_consul.h
@@ -0,0 +1,18 @@
+#ifndef __PANGU_VALVE_CONSUL_H__
+#define __PANGU_VALVE_CONSUL_H__
+
+#include <sys/types.h>
+
+struct easy_string
+{
+ char* buff;
+ size_t len;
+ size_t size;
+};
+
+bool consul_try_get_lock(const char *session_id, const char *key, const char *value, int timeout_s);
+bool consul_renew_session(const char *session_id, int timeout_s);
+bool consul_create_session(int lock_delay_s, int ttl_s, char *session_id, int size, void *runlog);
+
+#endif
+
diff --git a/src/pg_valve_deal.cpp b/src/pg_valve_deal.cpp
new file mode 100644
index 0000000..36e6d25
--- /dev/null
+++ b/src/pg_valve_deal.cpp
@@ -0,0 +1,1429 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <sys/prctl.h>
+#include <signal.h>
+
+#include <MESA/MESA_htable.h>
+#include <MESA/field_stat2.h>
+#include <MESA/Maat_rule.h>
+
+#include "pg_valve_deal.h"
+#include "pg_valve_main.h"
+#include "pg_valve_maat.h"
+#include "pg_valve_stat.h"
+
+extern pgvavle_global_info_t g_pgvalve_info;
+
+SSCANF_ERROR_NO_t _wrap_grule_check(grule_t *grule);
+
+const char*sscanf_error_string(SSCANF_ERROR_NO_t type)
+{
+ switch(type)
+ {
+ case SSCANF_ERROR_NUM: return "filed num wrong";
+ case SSCANF_ERROR_DID: return "did is null";
+ case SSCANF_ERROR_DSETID: return "appid is null";
+ case SSCANF_ERROR_SERVICE: return "service unrecognized";
+ case SSCANF_ERROR_IP: return "ipaddr format wrong";
+ case SSCANF_ERROR_TUPLE: return "tuple combination invalid";
+ case SSCANF_ERROR_LIMIT: return "limit rate is null";
+ case SSCANF_ERROR_RULE: return "ip/port and/or mask content invalid";
+ default: return "unknown";
+ }
+}
+
+SSCANF_ERROR_NO_t fill_in_dsetid_did_limitid(const char *user_region, int64_t *did,int64_t *dsetid, int32_t *limit_rate)
+{
+ const char *pos;
+
+ if(did!=NULL && NULL!=(pos = strcasestr(user_region, "DOMAIN_ID=")))
+ {
+ if(sscanf(pos+strlen("DOMAIN_ID="), "%ld", did) != 1)
+ {
+ return SSCANF_ERROR_DID;
+ }
+ }
+
+ if(dsetid!=NULL && NULL!=(pos = strcasestr(user_region, "APP_ID=")))
+ {
+ if(sscanf(pos+strlen("APP_ID="), "%ld", dsetid) != 1)
+ {
+ return SSCANF_ERROR_DSETID;
+ }
+ }
+
+ if(limit_rate!=NULL && NULL!=(pos = strcasestr(user_region, "RATE_LIMIT=")))
+ {
+ if(sscanf(pos+strlen("RATE_LIMIT="), "%d", limit_rate) != 1)
+ {
+ return SSCANF_ERROR_LIMIT;
+ }
+ }
+
+ return SSCANF_OK;
+}
+
+void one_destroy_hnode(void *data)
+{
+ free(data);
+}
+
+//��RuleidΪKEY
+//Return: 1-�·���0-���·�
+int64_t one_deal_config_incr_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ one_config_hnode_t *hnode = (one_config_hnode_t *)data;
+ htable_privdata_t *priv = (htable_privdata_t *)arg;
+ configure_table_t *table = priv->table;
+ int32_t ret;
+
+ if(hnode != NULL)
+ {
+ priv->iprule.disp_status = hnode->disp_status;
+ }
+
+ //��֤����һ������һ�Σ������ʧ�ܣ��´�����������
+ ret = dispatch_config_to_c3(priv->table->table_name, priv->table->service_id, priv->table->table_id_key, priv->iprule);
+ if(hnode != NULL)
+ {
+ //���ɾ��ʧ�ܣ�������ڴ棬ռ��һ���ռ䣬�����־����������
+ if(priv->iprule.disp_status==0 && priv->iprule.grule.action == GRULE_ACTION_DEL)
+ {
+ MESA_htable_del(table->hash_handle, key, size, one_destroy_hnode);
+ }
+ else
+ {
+ if(priv->iprule.grule.action == GRULE_ACTION_DEL) //δɾ���ɹ��ģ����Ϊɾ��״̬
+ {
+ hnode->grule.action = GRULE_ACTION_DEL;
+ }
+ hnode->disp_status = priv->iprule.disp_status;
+ }
+ }
+ else if(ret != DISP_LIMIT && (priv->iprule.grule.action == GRULE_ACTION_ADD))
+ {
+ hnode = (one_config_hnode_t *)calloc(1, sizeof(one_config_hnode_t));
+ if((ret = MESA_htable_add(table->hash_handle, key, size, hnode)) < 0)
+ {
+ free(hnode);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s, MESA_htable_add failed: %d, ruleid: %u", table->table_name, ret, priv->iprule.grule.rule_id);
+ pz_trans_statistic_count(table->service_id, table->table_id_key, 1, STAT_FIELD_DISP_FAIL);
+ return -1;
+ }
+ hnode->grule = priv->iprule.grule;
+ hnode->disp_status = priv->iprule.disp_status;
+ }
+
+ return ret;
+}
+
+void one_maat_start_callback(int32_t update_type, void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+
+ maat_data->update_type = update_type;
+
+ if(maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_FULL))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s recv another full config, restart.", maat_data->table->table_name);
+ exit(10);
+ }
+ if(!maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_INC))
+ {
+ maat_data->table->over_flag = true;
+ }
+}
+
+SSCANF_ERROR_NO_t fill_in_region_grule_ip(const char* table_line, one_config_hnode_t *iprule)
+{
+ int32_t ret, addr_type, protocol, direction, is_valid, action, service, limit_rate=0;
+ int64_t region_id, group_id;
+ char src_ip[128], src_ip_mask[128], src_port[20], src_port_mask[20];
+ char dst_ip[128], dst_ip_mask[128], dst_port[20], dst_port_mask[20], user_region[4096]={0};
+ grule_map_info_t gmap_info;
+
+ user_region[0] = 0;
+ ret = sscanf(table_line, "%ld\t%ld\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\t%s",
+ &region_id, &group_id, &addr_type,
+ src_ip, src_ip_mask, src_port, src_port_mask,
+ dst_ip, dst_ip_mask, dst_port, dst_port_mask,
+ &protocol, &direction, &is_valid,
+ &action, &service, user_region);
+ if(ret != 16 && ret!=17) //user_regionֻ�����ٱ���
+ {
+ return SSCANF_ERROR_NUM;
+ }
+ iprule->disp_status = 0;
+ iprule->grule.rule_id = region_id;
+ if(fill_in_dsetid_did_limitid(user_region, NULL, NULL, &limit_rate))
+ return SSCANF_ERROR_LIMIT;
+ if(service_to_c3_servtype(service, (limit_rate/10)*10, &gmap_info))
+ return SSCANF_ERROR_SERVICE;
+ iprule->grule.srv_type = gmap_info.serv_type;
+ iprule->grule.rule_scope = gmap_info.rule_scope;
+ iprule->grule.durable = 1;
+ iprule->grule.action = is_valid?GRULE_ACTION_ADD:GRULE_ACTION_DEL;
+ iprule->grule.rule_type.grule_type = 0;
+ iprule->grule.rule_type.ddir_flag = (direction==G_DIR_DOUBLE)?1:0;
+
+ switch(addr_type)
+ {
+ case 4:
+ if(inet_pton(AF_INET, src_ip, &iprule->grule.m4.sip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET, src_ip_mask, &iprule->grule.m4.sip_mask) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET, dst_ip, &iprule->grule.m4.dip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET, dst_ip_mask, &iprule->grule.m4.dip_mask) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.m4.sport = ntohs(atoi(src_port));
+ iprule->grule.m4.sport_mask = ntohs(atoi(src_port_mask));
+ iprule->grule.m4.dport = ntohs(atoi(dst_port));
+ iprule->grule.m4.dport_mask = ntohs(atoi(dst_port_mask));
+ iprule->grule.m4.proto = protocol;
+ iprule->grule.m4.proto_mask = ~0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_MASK4;
+
+ iprule->grule.rule_type.sip_flag = (iprule->grule.m4.sip!=0)?1:0;
+ iprule->grule.rule_type.sipmsk_flag = (iprule->grule.m4.sip!=0&&iprule->grule.m4.sip_mask!=0)?1:0;
+ iprule->grule.rule_type.dip_flag = (iprule->grule.m4.dip!=0)?1:0;
+ iprule->grule.rule_type.dipmsk_flag = (iprule->grule.m4.dip!=0&&iprule->grule.m4.dip_mask!=0)?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.m4.sport!=0)?1:0;
+ iprule->grule.rule_type.spmsk_flag = (iprule->grule.m4.sport!=0&&iprule->grule.m4.sport_mask!=0)?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.m4.dport!=0)?1:0;
+ iprule->grule.rule_type.dpmsk_flag= (iprule->grule.m4.dport!=0&&iprule->grule.m4.dport_mask!=0)?1:0;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.rule_type.pmsk_flag = ((iprule->grule.rule_type.sipmsk_flag||iprule->grule.rule_type.dipmsk_flag) && protocol!=0)?1:0;
+ break;
+
+ case 6:
+ if(inet_pton(AF_INET6, src_ip, iprule->grule.m6.sip.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET6, src_ip_mask, iprule->grule.m6.sip_mask.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET6, dst_ip, iprule->grule.m6.dip.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET6, dst_ip_mask, iprule->grule.m6.dip_mask.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.m6.sport = ntohs(atoi(src_port));
+ iprule->grule.m6.sport_mask = ntohs(atoi(src_port_mask));
+ iprule->grule.m6.dport = ntohs(atoi(dst_port));
+ iprule->grule.m6.dport_mask = ntohs(atoi(dst_port_mask));
+ iprule->grule.m6.proto = protocol;
+ iprule->grule.m6.proto_mask = ~0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_MASK6;
+
+ iprule->grule.rule_type.sip_flag = (iprule->grule.m6.sip.ip6_l[0] | iprule->grule.m6.sip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.sipmsk_flag = ((iprule->grule.m6.sip.ip6_l[0] | iprule->grule.m6.sip.ip6_l[1])&&(iprule->grule.m6.sip_mask.ip6_l[0] | iprule->grule.m6.sip_mask.ip6_l[1]))?1:0;
+ iprule->grule.rule_type.dip_flag = (iprule->grule.m6.dip.ip6_l[0] | iprule->grule.m6.dip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.dipmsk_flag = ((iprule->grule.m6.dip.ip6_l[0] | iprule->grule.m6.dip.ip6_l[1])&&(iprule->grule.m6.dip_mask.ip6_l[0] | iprule->grule.m6.dip_mask.ip6_l[1]))?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.m6.sport!=0)?1:0;
+ iprule->grule.rule_type.spmsk_flag = (iprule->grule.m6.sport!=0&&iprule->grule.m6.sport_mask!=0)?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.m6.dport!=0)?1:0;
+ iprule->grule.rule_type.dpmsk_flag= (iprule->grule.m6.dport!=0&&iprule->grule.m6.dport_mask!=0)?1:0;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.rule_type.pmsk_flag = ((iprule->grule.rule_type.sipmsk_flag||iprule->grule.rule_type.dipmsk_flag) && protocol!=0)?1:0;
+ break;
+ default:
+ assert(0);
+ return SSCANF_ERROR_PROTOCOL;
+ }
+
+ return SSCANF_OK;
+}
+
+SSCANF_ERROR_NO_t fill_in_region_grule_pool(const char* table_line, one_config_hnode_t *iprule)
+{
+ int32_t ret, addr_type, direction, location, is_valid, service, protocol, limit_rate=0;
+ int64_t region_id;
+ char ipaddr[128], port[8], user_region[4096];
+ grule_map_info_t gmap_info;
+
+ ret = sscanf(table_line, "%ld\t%d\t%d\t%s\t%s\t%d\t%s\t%d\t%d\t%d",
+ &region_id, &addr_type, &protocol, ipaddr, port, &direction, user_region, &location, &is_valid, &service);
+ if(ret != 10)
+ {
+ return SSCANF_ERROR_NUM;
+ }
+ iprule->disp_status = 0;
+ iprule->grule.rule_id = region_id;
+ if(fill_in_dsetid_did_limitid(user_region, NULL, NULL, &limit_rate))
+ return SSCANF_ERROR_LIMIT;
+ if(service_to_c3_servtype(service, (limit_rate/10)*10, &gmap_info))
+ return SSCANF_ERROR_SERVICE;
+ iprule->grule.srv_type = gmap_info.serv_type;
+ iprule->grule.rule_scope = gmap_info.rule_scope;
+ iprule->grule.durable = 1;
+ iprule->grule.action = is_valid?GRULE_ACTION_ADD:GRULE_ACTION_DEL;
+ iprule->grule.rule_type.grule_type = 0;
+ iprule->grule.rule_type.ddir_flag = (direction==G_DIR_DOUBLE)?1:0;
+
+ switch(addr_type)
+ {
+ case 4:
+ if(direction == G_DIR_S2C)
+ {
+ if(inet_pton(AF_INET, ipaddr, &iprule->grule.s4.dip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s4.dport = ntohs(atoi(port));
+ iprule->grule.rule_type.dip_flag = (iprule->grule.s4.dip!=0)?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.s4.dport!=0)?1:0;
+ }
+ else
+ {
+ if(inet_pton(AF_INET, ipaddr, &iprule->grule.s4.sip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s4.sport = ntohs(atoi(port));
+ iprule->grule.rule_type.sip_flag = (iprule->grule.s4.sip!=0)?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.s4.sport!=0)?1:0;
+ }
+ iprule->grule.s4.proto = protocol;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_SIMPLE4;
+ break;
+
+ case 6:
+ if(direction == G_DIR_S2C)
+ {
+ if(inet_pton(AF_INET6, ipaddr, &iprule->grule.s6.dip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s6.dport = ntohs(atoi(port));
+ iprule->grule.rule_type.dip_flag = (iprule->grule.s6.dip.ip6_l[0] | iprule->grule.s6.dip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.s6.dport!=0)?1:0;
+ }
+ else
+ {
+ if(inet_pton(AF_INET6, ipaddr, &iprule->grule.s6.sip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s6.sport = ntohs(atoi(port));
+ iprule->grule.rule_type.sip_flag = (iprule->grule.s6.sip.ip6_l[0] | iprule->grule.s6.sip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.s6.sport!=0)?1:0;
+ }
+ iprule->grule.s6.proto = protocol;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_SIMPLE6;
+ break;
+ default:
+ return SSCANF_ERROR_PROTOCOL;
+ }
+
+ return SSCANF_OK;
+}
+
+void one_maat_update_callback(int32_t table_id, const char* table_line, void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+ table_hash_key_t hash_key;
+ htable_privdata_t priv;
+ int64_t cb_ret;
+ SSCANF_ERROR_NO_t code, check;
+
+ memset(&priv, 0 ,sizeof(htable_privdata_t));
+ switch(maat_data->table->region_type)
+ {
+ case REGION_TYPE_IP:
+ code = fill_in_region_grule_ip(table_line, &priv.iprule);
+ break;
+ case REGION_TYPE_POOL:
+ code = fill_in_region_grule_pool(table_line, &priv.iprule);
+ break;
+ default:
+ assert(0);return;
+ }
+ if(code!=SSCANF_OK || (check=_wrap_grule_check(&priv.iprule.grule)))
+ {
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, STAT_FIELD_RERROR);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_error: %s, table %s, line: %s",
+ sscanf_error_string((code!=SSCANF_OK)?code:check), maat_data->table->table_name, table_line);
+ return ;
+ }
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, (priv.iprule.grule.action==GRULE_ACTION_ADD)?STAT_FIELD_RVALID:STAT_FIELD_RINVALID);
+
+ priv.table = maat_data->table;
+ priv.dsetid = 0;
+ priv.did = 0;
+
+ hash_key.service_id = maat_data->table->service_id;
+ hash_key.table_id = maat_data->table->table_id_key;
+ hash_key.dsetid = 0;
+ hash_key.did = priv.iprule.grule.rule_id;
+
+ pthread_rwlock_rdlock(&g_pgvalve_info.rwlock);
+ MESA_htable_search_cb(maat_data->table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), one_deal_config_incr_cb, (void*)&priv, &cb_ret);
+ pthread_rwlock_unlock(&g_pgvalve_info.rwlock);
+}
+
+void one_maat_finish_callback(void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+ //int32_t last_table = 0;
+ //int64_t version;
+
+ //���û��ȫ�����᲻�����?
+ if(maat_data->update_type == MAAT_RULE_UPDATE_TYPE_FULL)
+ {
+ maat_data->table->over_flag = true;
+ }
+
+ /*���°汾�ţ���ʱ����
+ Maat_read_state(maat_data->maat_service->get_maat_feather(), MAAT_STATE_LAST_UPDATING_TABLE, &last_table, sizeof(last_table));
+ if(last_table)
+ {
+ Maat_read_state(maat_data->maat_service->get_maat_feather(), MAAT_STATE_VERSION, &version, sizeof(version));
+ maat_data->maat_service->store_latest_version(version);
+ }*/
+}
+
+configure_table_t *new_table_instance_one(const char *table_name, int32_t service_id, int32_t table_id, int32_t region_type, MESA_htable_handle hash_handle)
+{
+ configure_table_t *table_one;
+
+ table_one = (configure_table_t *)calloc(1, sizeof(configure_table_t));
+ table_one->table_name = table_name;
+ table_one->service_id = service_id;
+ table_one->hash_handle = hash_handle;
+ table_one->over_flag = false;
+ table_one->region_type = region_type;
+ table_one->table_id_key = table_id;
+
+ table_one->maat_start_cb = one_maat_start_callback;
+ table_one->maat_update_cb= one_maat_update_callback;
+ table_one->maat_finish_cb= one_maat_finish_callback;
+ return table_one;
+}
+
+//disp_activeͳһ������Ч��ʧЧ������(�������������)
+//�������������ã���֤iprule.disp_statusΪ0
+static int32_t onesw_update_config_set_full(const char *table_name, int service_id, int table_id, onesw_config_hnode_t *hnode, one_config_hnode_t &iprule, bool disp_active)
+{
+ int ret = 0;
+
+ if(iprule.grule.action == GRULE_ACTION_ADD)
+ {
+ if(hnode->full.find(iprule.grule.rule_id) != hnode->full.end())
+ {
+ hnode->full[iprule.grule.rule_id].grule = iprule.grule; //�¼ӵĸ���(��ԭ��������DEL�����ܸ����·�״̬)
+ }
+ else
+ {
+ hnode->full[iprule.grule.rule_id] = iprule;
+ }
+ if(disp_active)
+ {
+ ret = dispatch_config_to_c3(table_name, service_id, table_id, hnode->full[iprule.grule.rule_id]);
+ if(ret==DISP_LIMIT && hnode->full[iprule.grule.rule_id].disp_status==0) //�������ޣ���֮ǰδ�·�
+ {
+ hnode->full.erase(iprule.grule.rule_id);
+ }
+ }
+ }
+ else
+ {
+ if(disp_active)
+ {
+ if(hnode->full.find(iprule.grule.rule_id) != hnode->full.end())
+ {
+ iprule.disp_status = hnode->full[iprule.grule.rule_id].disp_status;
+ ret = dispatch_config_to_c3(table_name, service_id, table_id, iprule);
+ hnode->full[iprule.grule.rule_id].disp_status = iprule.disp_status;
+ }
+ else
+ {
+ ret = dispatch_config_to_c3(table_name, service_id, table_id, iprule);
+ }
+ }
+
+ //δɾ���ɹ�������������Ȼ�´�ʧЧ������ʱ���޷��������޼���
+ if(hnode->full.find(iprule.grule.rule_id) != hnode->full.end())
+ {
+ if(hnode->full[iprule.grule.rule_id].disp_status == 0)
+ {
+ hnode->full.erase(iprule.grule.rule_id);
+ }
+ else
+ { //δɾ���ɹ��ģ����Ϊɾ��״̬
+ hnode->full[iprule.grule.rule_id].grule.action = GRULE_ACTION_DEL;
+ }
+ }
+ }
+
+ return ret;
+}
+
+//�����״�ȫ���Լ���������
+int64_t onesw_deal_config_incr_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ onesw_config_hnode_t *hnode = (onesw_config_hnode_t *)data;
+ htable_privdata_t *priv = (htable_privdata_t *)arg;
+ configure_table_t *table = priv->table;
+ int32_t ret;
+ swtable_state_t sw_state;
+
+ if(hnode == NULL)
+ {
+ hnode = new __onesw_config_hnode();
+ if((ret = MESA_htable_add(table->hash_handle, key, size, hnode)) < 0)
+ {
+ delete hnode;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s, MESA_htable_add failed: %d, ruleid: %u", table->table_name, ret, priv->iprule.grule.rule_id);
+ pz_trans_statistic_count(table->service_id, table->table_id_key, 1, STAT_FIELD_DISP_FAIL);
+ return -1;
+ }
+ hnode->dsetid= priv->dsetid;
+ hnode->did = priv->did;
+ }
+
+ if(!table->parent->get_hnode_sw_action_recur(table->parent, priv->dsetid, priv->did, &sw_state))
+ {
+ onesw_update_config_set_full(priv->table->table_name, priv->table->service_id, priv->table->table_id_key, hnode, priv->iprule, false);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_DEBUG, MODULE_NAME, "pz_dispatch: onesw table %s dsetid=%lu;did=%lu;cfgid=%lu dont dispatch because parent is not exist.",
+ table->table_name, priv->dsetid, priv->did, priv->iprule.grule.rule_id);
+ return 0;
+ }
+
+ priv->iprule.grule.srv_type = sw_state.gmap_info.serv_type;
+ priv->iprule.grule.rule_scope = sw_state.gmap_info.rule_scope;
+ if(sw_state.switcher == SW_STAT_DEACTIVATE)
+ {
+ onesw_update_config_set_full(priv->table->table_name, priv->table->service_id, priv->table->table_id_key, hnode, priv->iprule, false);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_DEBUG, MODULE_NAME, "pz_dispatch: onesw table %s dsetid=%lu;did=%lu;cfgid=%lu dont dispatch because parent is closed.",
+ table->table_name, priv->dsetid, priv->did, priv->iprule.grule.rule_id);
+ return 0;
+ }
+
+ onesw_update_config_set_full(priv->table->table_name, priv->table->service_id, priv->table->table_id_key, hnode, priv->iprule, true);
+ return 1;
+}
+
+//������������DID���Ͽ���
+static int64_t onesw_drive_full_cfg_by_two_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ onesw_config_hnode_t *hnode = (onesw_config_hnode_t *)data;
+ htable_privdata_t *priv = (htable_privdata_t *)arg;
+ map<int64_t, one_config_hnode_t>::iterator iter;
+ int ret=0;
+
+ if(hnode != NULL)
+ {
+ for(iter=hnode->full.begin(); iter!=hnode->full.end() && ret!=DISP_RETRY; )
+ {
+ one_config_hnode_t iprule = iter->second; //�洢�Ŀ�����ʧЧ��(ɾ��δ�ɹ�)
+
+ iprule.grule.srv_type = priv->gmap_info.serv_type;
+ iprule.grule.rule_scope = priv->gmap_info.rule_scope;
+ if(priv->did_switch == SW_STAT_DEACTIVATE)
+ {
+ iprule.grule.action = GRULE_ACTION_DEL;
+ }
+
+ ret = dispatch_config_to_c3(priv->table->table_name, priv->table->service_id, priv->table->table_id_key, iprule);
+ iter->second.disp_status = iprule.disp_status;
+ if(iprule.disp_status == 0 && (iter->second.grule.action == GRULE_ACTION_DEL || ret==DISP_LIMIT))
+ {
+ hnode->full.erase(iter++); //map����ɾ��������
+ }
+ else
+ {
+ iter++;
+ }
+ }
+ }
+
+ return ret;
+}
+
+int32_t onesw_drive_full_cfg_by_two(configure_table_t *table, int64_t dsetid, int64_t did, swtable_state_t *sw_state)
+{
+ table_hash_key_t hash_key;
+ htable_privdata_t priv;
+ int64_t cb_ret;
+
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = did;
+
+ priv.table = table;
+ priv.dsetid = dsetid;
+ priv.did = did;
+ priv.did_switch = sw_state->switcher;
+ priv.gmap_info = sw_state->gmap_info;
+
+ MESA_htable_search_cb(table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), onesw_drive_full_cfg_by_two_cb, (void*)&priv, &cb_ret);
+ return cb_ret;
+}
+
+void onesw_maat_start_callback(int32_t update_type,void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+
+ maat_data->update_type = update_type;
+
+ if(maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_FULL))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s recv another full config, restart.", maat_data->table->table_name);
+ exit(10);
+ }
+ if(!maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_INC))
+ {
+ maat_data->table->over_flag = true;
+ }
+}
+
+SSCANF_ERROR_NO_t onesw_fill_in_region_grule_ip(const char* table_line, one_config_hnode_t *iprule, int64_t *did, int64_t *dsetid)
+{
+ int32_t ret, addr_type, protocol, direction, is_valid, action, service;
+ int64_t region_id, group_id;
+ char src_ip[128], src_ip_mask[128], src_port[8], src_port_mask[8];
+ char dst_ip[128], dst_ip_mask[128], dst_port[8], dst_port_mask[8];
+ char user_region[4096];
+
+ ret = sscanf(table_line, "%ld\t%ld\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\t%s",
+ &region_id, &group_id, &addr_type,
+ src_ip, src_ip_mask, src_port, src_port_mask,
+ dst_ip, dst_ip_mask, dst_port, dst_port_mask,
+ &protocol, &direction, &is_valid,
+ &action, &service, user_region);
+ if(ret != 17)
+ {
+ return SSCANF_ERROR_NUM;
+ }
+ iprule->disp_status = 0;
+ iprule->grule.rule_id = region_id;
+ iprule->grule.durable = 1;
+ iprule->grule.action = is_valid?GRULE_ACTION_ADD:GRULE_ACTION_DEL;
+ iprule->grule.rule_type.grule_type = 0;
+ iprule->grule.rule_type.ddir_flag = (direction==G_DIR_DOUBLE)?1:0;
+
+ switch(addr_type)
+ {
+ case 4:
+ if(inet_pton(AF_INET, src_ip, &iprule->grule.m4.sip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET, src_ip_mask, &iprule->grule.m4.sip_mask) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET, dst_ip, &iprule->grule.m4.dip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET, dst_ip_mask, &iprule->grule.m4.dip_mask) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.m4.sport = ntohs(atoi(src_port));
+ iprule->grule.m4.sport_mask = ntohs(atoi(src_port_mask));
+ iprule->grule.m4.dport = ntohs(atoi(dst_port));
+ iprule->grule.m4.dport_mask = ntohs(atoi(dst_port_mask));
+ iprule->grule.m4.proto = protocol;
+ iprule->grule.m4.proto_mask = ~0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_MASK4;
+
+ iprule->grule.rule_type.sip_flag = (iprule->grule.m4.sip!=0)?1:0;
+ iprule->grule.rule_type.sipmsk_flag = (iprule->grule.m4.sip!=0&&iprule->grule.m4.sip_mask!=0)?1:0;
+ iprule->grule.rule_type.dip_flag = (iprule->grule.m4.dip!=0)?1:0;
+ iprule->grule.rule_type.dipmsk_flag = (iprule->grule.m4.dip!=0&&iprule->grule.m4.dip_mask!=0)?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.m4.sport!=0)?1:0;
+ iprule->grule.rule_type.spmsk_flag = (iprule->grule.m4.sport!=0&&iprule->grule.m4.sport_mask!=0)?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.m4.dport!=0)?1:0;
+ iprule->grule.rule_type.dpmsk_flag= (iprule->grule.m4.dport!=0&&iprule->grule.m4.dport_mask!=0)?1:0;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.rule_type.pmsk_flag = ((iprule->grule.rule_type.sipmsk_flag||iprule->grule.rule_type.dipmsk_flag) && protocol!=0)?1:0;
+ break;
+
+ case 6:
+ if(inet_pton(AF_INET6, src_ip, iprule->grule.m6.sip.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET6, src_ip_mask, iprule->grule.m6.sip_mask.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET6, dst_ip, iprule->grule.m6.dip.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ if(inet_pton(AF_INET6, dst_ip_mask, iprule->grule.m6.dip_mask.ip6_c) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.m6.sport = ntohs(atoi(src_port));
+ iprule->grule.m6.sport_mask = ntohs(atoi(src_port_mask));
+ iprule->grule.m6.dport = ntohs(atoi(dst_port));
+ iprule->grule.m6.dport_mask = ntohs(atoi(dst_port_mask));
+ iprule->grule.m6.proto = protocol;
+ iprule->grule.m6.proto_mask = ~0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_MASK6;
+
+ iprule->grule.rule_type.sip_flag = (iprule->grule.m6.sip.ip6_l[0] | iprule->grule.m6.sip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.sipmsk_flag = ((iprule->grule.m6.sip.ip6_l[0] | iprule->grule.m6.sip.ip6_l[1])&&(iprule->grule.m6.sip_mask.ip6_l[0] | iprule->grule.m6.sip_mask.ip6_l[1]))?1:0;
+ iprule->grule.rule_type.dip_flag = (iprule->grule.m6.dip.ip6_l[0] | iprule->grule.m6.dip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.dipmsk_flag = ((iprule->grule.m6.dip.ip6_l[0] | iprule->grule.m6.dip.ip6_l[1])&&(iprule->grule.m6.dip_mask.ip6_l[0] | iprule->grule.m6.dip_mask.ip6_l[1]))?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.m6.sport!=0)?1:0;
+ iprule->grule.rule_type.spmsk_flag = (iprule->grule.m6.sport!=0&&iprule->grule.m6.sport_mask!=0)?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.m6.dport!=0)?1:0;
+ iprule->grule.rule_type.dpmsk_flag= (iprule->grule.m6.dport!=0&&iprule->grule.m6.dport_mask!=0)?1:0;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.rule_type.pmsk_flag = ((iprule->grule.rule_type.sipmsk_flag||iprule->grule.rule_type.dipmsk_flag) && protocol!=0)?1:0;
+ break;
+ default:
+ return SSCANF_ERROR_PROTOCOL;
+ }
+
+ return fill_in_dsetid_did_limitid(user_region, did, dsetid, NULL);
+}
+
+SSCANF_ERROR_NO_t onesw_fill_in_region_grule_find(const char* table_line, one_config_hnode_t *iprule, int64_t *did,int64_t *dsetid)
+{
+ int32_t ret, addr_type, protocol, direction, location, is_valid;
+ int64_t region_id;
+ char ipaddr[128], port[8], user_region[4096];
+
+ ret = sscanf(table_line, "%ld\t%d\t%d\t%s\t%s\t%d\t%s\t%d\t%d",
+ &region_id, &addr_type, &protocol, ipaddr, port, &direction, user_region, &location, &is_valid);
+ if(ret != 9)
+ {
+ return SSCANF_ERROR_NUM;
+ }
+ iprule->disp_status = 0;
+ iprule->grule.rule_id = region_id;
+ iprule->grule.durable = 1;
+ iprule->grule.action = is_valid?GRULE_ACTION_ADD:GRULE_ACTION_DEL;
+ iprule->grule.rule_type.grule_type = 0;
+ iprule->grule.rule_type.ddir_flag = (direction==G_DIR_DOUBLE)?1:0;
+
+ switch(addr_type)
+ {
+ case 4:
+ if(direction == G_DIR_S2C)
+ {
+ if(inet_pton(AF_INET, ipaddr, &iprule->grule.s4.dip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s4.dport = ntohs(atoi(port));
+ iprule->grule.rule_type.dip_flag = (iprule->grule.s4.dip!=0)?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.s4.dport!=0)?1:0;
+ }
+ else
+ {
+ if(inet_pton(AF_INET, ipaddr, &iprule->grule.s4.sip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s4.sport = ntohs(atoi(port));
+ iprule->grule.rule_type.sip_flag = (iprule->grule.s4.sip!=0)?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.s4.sport!=0)?1:0;
+ }
+ iprule->grule.s4.proto = protocol;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_SIMPLE4;
+ break;
+
+ case 6:
+ if(direction == G_DIR_S2C)
+ {
+ if(inet_pton(AF_INET6, ipaddr, &iprule->grule.s6.dip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s6.dport = ntohs(atoi(port));
+ iprule->grule.rule_type.dip_flag = (iprule->grule.s6.dip.ip6_l[0] | iprule->grule.s6.dip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.dport_flag = (iprule->grule.s6.dport!=0)?1:0;
+ }
+ else
+ {
+ if(inet_pton(AF_INET6, ipaddr, &iprule->grule.s6.sip) != 1)
+ {
+ return SSCANF_ERROR_IP;
+ }
+ iprule->grule.s6.sport = ntohs(atoi(port));
+ iprule->grule.rule_type.sip_flag = (iprule->grule.s6.sip.ip6_l[0] | iprule->grule.s6.sip.ip6_l[1])?1:0;
+ iprule->grule.rule_type.sport_flag = (iprule->grule.s6.sport!=0)?1:0;
+ }
+ iprule->grule.s6.proto = protocol;
+ iprule->grule.rule_type.proto_flag = (protocol!=0)?1:0;
+ iprule->grule.big_type = GRULE_BIG_TYPE_SIMPLE6;
+ break;
+ default:
+ return SSCANF_ERROR_PROTOCOL;
+ }
+
+ return fill_in_dsetid_did_limitid(user_region, did, dsetid, NULL);
+}
+
+void onesw_maat_update_callback(int32_t table_id,const char* table_line,void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+ table_hash_key_t hash_key;
+ htable_privdata_t priv;
+ int64_t cb_ret, dsetid=0, did=0;
+ SSCANF_ERROR_NO_t code, check;
+
+ memset(&priv, 0 ,sizeof(htable_privdata_t));
+ switch(maat_data->table->region_type)
+ {
+ case REGION_TYPE_IP:
+ code = onesw_fill_in_region_grule_ip(table_line, &priv.iprule, &did, &dsetid);
+ break;
+ case REGION_TYPE_FIND:
+ code = onesw_fill_in_region_grule_find(table_line, &priv.iprule, &did, &dsetid);
+ break;
+ default: return;
+ }
+ if(code!=SSCANF_OK || (did==0 && dsetid==0) || (check=_wrap_grule_check(&priv.iprule.grule)))
+ {
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, STAT_FIELD_RERROR);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_error: %s, table %s, line: %s",
+ sscanf_error_string(code!=SSCANF_OK?code:((did==0 && dsetid==0)?SSCANF_ERROR_DID:check)), maat_data->table->table_name, table_line);
+ return ;
+ }
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, (priv.iprule.grule.action==GRULE_ACTION_ADD)?STAT_FIELD_RVALID:STAT_FIELD_RINVALID);
+
+ priv.table = maat_data->table;
+ priv.dsetid = dsetid;
+ priv.did = did;
+
+ hash_key.service_id = maat_data->table->service_id;
+ hash_key.table_id = maat_data->table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = (maat_data->table->parent->parent!=NULL)?did:0;
+
+ pthread_rwlock_rdlock(&g_pgvalve_info.rwlock);
+ MESA_htable_search_cb(maat_data->table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), onesw_deal_config_incr_cb, (void*)&priv, &cb_ret);
+ pthread_rwlock_unlock(&g_pgvalve_info.rwlock);
+}
+
+void onesw_maat_finish_callback(void* u_para)
+{
+ one_maat_finish_callback(u_para);
+}
+
+configure_table_t *new_table_instance_onesw(const char *table_name, int32_t service_id, int32_t table_id, int32_t region_type, MESA_htable_handle hash_handle)
+{
+ configure_table_t *table_onesw;
+
+ table_onesw = (configure_table_t *)calloc(1, sizeof(configure_table_t));
+ table_onesw->table_name = table_name;
+ table_onesw->service_id = service_id;
+ table_onesw->hash_handle = hash_handle;
+ table_onesw->over_flag = false;
+ table_onesw->region_type = region_type;
+ table_onesw->table_id_key = table_id;
+
+ table_onesw->drive_full_cfg_by_parent = onesw_drive_full_cfg_by_two;
+
+ table_onesw->maat_start_cb = onesw_maat_start_callback;
+ table_onesw->maat_update_cb= onesw_maat_update_callback;
+ table_onesw->maat_finish_cb= onesw_maat_finish_callback;
+ return table_onesw;
+}
+
+void two_destroy_hnode(void *data)
+{
+ two_config_hnode_t *hnode = (two_config_hnode_t *)data;
+ delete hnode;
+}
+
+//���Ӷ������ر���ϣԪ�أ����ؿ���״̬
+static int64_t two_get_hnode_sw_action_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ two_config_hnode_t *hnode = (two_config_hnode_t *)data;
+ swtable_state_t *sw_state = (swtable_state_t *)arg;
+
+ if(hnode == NULL)
+ {
+ return 0;
+ }
+
+ sw_state->switcher = hnode->sw_status;
+ sw_state->gmap_info = hnode->gmap_info;
+ return 1;
+}
+
+int32_t two_get_hnode_sw_action(configure_table_t *table, int64_t dsetid, int64_t did, swtable_state_t *sw_state)
+{
+ table_hash_key_t hash_key;
+ int64_t exist_two;
+
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = did;
+
+ MESA_htable_search_cb(table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), two_get_hnode_sw_action_cb, (void*)sw_state, &exist_two);
+ if(exist_two == 0)
+ {
+ return 0;
+ }
+
+ if(table->parent != NULL)
+ {
+ swtable_state_t sw_state_three;
+ if(!table->parent->get_hnode_sw_action_recur(table->parent, dsetid, did, &sw_state_three))
+ {
+ return 0;
+ }
+ sw_state->gmap_info = sw_state_three.gmap_info;
+ sw_state->switcher = (sw_state_three.switcher==SW_STAT_DEACTIVATE)?SW_STAT_DEACTIVATE:sw_state->switcher;
+ }
+
+ return 1;
+}
+
+//KEY: ServiceID+TableID+DSET+DID
+int64_t two_deal_config_incr_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ two_config_hnode_t *hnode = (two_config_hnode_t *)data;
+ htable_privdata_t *priv = (htable_privdata_t *)arg;
+ configure_table_t *table = priv->table;
+ int32_t ret;
+ swtable_state_t sw_state;
+ bool sw_parent= true;
+
+ if(hnode == NULL)
+ {
+ hnode = new __two_config_hnode();
+ if((ret = MESA_htable_add(table->hash_handle, key, size, hnode)) < 0)
+ {
+ delete hnode;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s, MESA_htable_add failed: %d, ruleid: %u", table->table_name, ret, priv->iprule.grule.rule_id);
+ pz_trans_statistic_count(table->service_id, table->table_id_key, 1, STAT_FIELD_DISP_FAIL);
+ return -1;
+ }
+ hnode->dsetid= priv->dsetid;
+ hnode->did = priv->did;
+ }
+ sw_state.gmap_info = hnode->gmap_info = priv->gmap_info;
+ sw_state.switcher = hnode->sw_status = priv->did_switch;
+ if(hnode->sw_status == SW_STAT_DEACTIVATE)
+ {
+ hnode->last_invalid = time(NULL);
+ }
+
+ if(table->parent != NULL)
+ {
+ swtable_state_t sw_state_three;
+
+ //���ڵ㼯��
+ table->parent->update_hnode_dset(table->parent, priv->dsetid, priv->did);
+ //������
+ if(!table->parent->get_hnode_sw_action_recur(table->parent, priv->dsetid, priv->did, &sw_state_three))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_DEBUG, MODULE_NAME, "pz_dispatch: table two %s, dsetid=%lu;did=%lu dont drive child because parent is not exist.", table->table_name, priv->dsetid, priv->did);
+ return 0;
+ }
+ sw_state.gmap_info = sw_state_three.gmap_info;
+ sw_state.switcher = (sw_state_three.switcher==SW_STAT_DEACTIVATE)?SW_STAT_DEACTIVATE:hnode->sw_status;
+ sw_parent = (sw_state_three.switcher==SW_STAT_ACTIVATE)?true:false;
+ }
+
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_DEBUG, MODULE_NAME, "pz_dispatch: table two %s dsetid=%lu;did=%lu, %s.",
+ table->table_name, priv->dsetid, priv->did, sw_parent?"drive onesw":"dont drive onesw because parent is closed");
+ if(sw_parent)
+ {
+ configure_table_t *child = table->child;
+ while(child != NULL)
+ {
+ child->drive_full_cfg_by_parent(child, hnode->dsetid, hnode->did, &sw_state);
+ child = child->next;
+ }
+ }
+ return 1;
+}
+
+int32_t two_drive_did_full_by_three(configure_table_t *table, int64_t dsetid, int64_t did, swtable_state_t *sw_state)
+{
+ table_hash_key_t hash_key;
+ int64_t two_exist;
+ swtable_state_t sw_state_two;
+ configure_table_t *child = table->child;
+
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = did;
+
+ MESA_htable_search_cb(table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), two_get_hnode_sw_action_cb, (void*)&sw_state_two, &two_exist);
+ if(!two_exist)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_DEBUG, MODULE_NAME, "pz_dispatch: table two %s desetid=%lu;did=%lu, drive full by three: drive onesw end becase two not exist.",
+ table->table_name, dsetid, did);
+ return 0;
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_DEBUG, MODULE_NAME, "pz_dispatch: table two %s desetid=%lu;did=%lu, drive full by three: %s.",
+ table->table_name, dsetid, did, (sw_state_two.switcher == SW_STAT_ACTIVATE)?"drive onesw":"drive onesw end because two is closed");
+
+ //������Ч�·�ʧ�ܵ������ֻ������һ��������������
+ //sw_stateָ�����������Ŀ��أ��˴��������������Ե����������Ŀ���
+ if(sw_state_two.switcher == SW_STAT_ACTIVATE)
+ {
+ while(child != NULL)
+ {
+ child->drive_full_cfg_by_parent(child, dsetid, did, sw_state);
+ child = child->next;
+ }
+ }
+ return 0;
+}
+
+void two_maat_start_callback(int32_t update_type,void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+
+ maat_data->update_type = update_type;
+
+ if(maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_FULL))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s recv another full config, restart.", maat_data->table->table_name);
+ exit(10);
+ }
+ if(!maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_INC))
+ {
+ maat_data->table->over_flag = true;
+ }
+}
+
+void two_maat_update_callback(int32_t table_id,const char* table_line,void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+ table_hash_key_t hash_key;
+ htable_privdata_t priv;
+ int64_t cb_ret, dsetid=0, did=0;
+ int32_t region_id, group_id, expr_type, match_method,is_hexbin,is_valid, service, action, limit_rate=0;
+ char keywods[1024], user_region[4096];
+
+ memset(&priv, 0 ,sizeof(htable_privdata_t));
+ cb_ret = sscanf(table_line, "%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%s",
+ &region_id, &group_id, keywods, &expr_type, &match_method, &is_hexbin, &is_valid, &action, &service, user_region);
+ if(cb_ret!=10 || fill_in_dsetid_did_limitid(user_region, &did, &dsetid, &limit_rate) || did==0 || (maat_data->table->parent!=NULL && dsetid==0))
+ {
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, STAT_FIELD_RERROR);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_error: table %s invalid line: %s", maat_data->table->table_name, table_line);
+ return ;
+ }
+ if(maat_data->table->parent==NULL && service_to_c3_servtype(service, (limit_rate/10)*10, &priv.gmap_info))
+ {
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, STAT_FIELD_RERROR);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_error: table %s service type error: %s", maat_data->table->table_name, table_line);
+ return ;
+ }
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, is_valid?STAT_FIELD_RVALID:STAT_FIELD_RINVALID);
+
+ priv.table = maat_data->table;
+ priv.dsetid = dsetid;
+ priv.did = did;
+ priv.did_switch = is_valid?SW_STAT_ACTIVATE:SW_STAT_DEACTIVATE;
+
+ hash_key.service_id = maat_data->table->service_id;
+ hash_key.table_id = maat_data->table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = did;
+
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_recv: table %s, region_id: %u, is_valid: %d, user_region: %s",
+ maat_data->table->table_name, region_id, is_valid, user_region);
+
+ pthread_rwlock_rdlock(&g_pgvalve_info.rwlock);
+ MESA_htable_search_cb(maat_data->table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), two_deal_config_incr_cb, (void*)&priv, &cb_ret);
+ pthread_rwlock_unlock(&g_pgvalve_info.rwlock);
+}
+
+void two_maat_finish_callback(void* u_para)
+{
+ one_maat_finish_callback(u_para);
+}
+
+configure_table_t *new_table_instance_two(const char *table_name, int32_t service_id, int32_t table_id, MESA_htable_handle hash_handle)
+{
+ configure_table_t *table_two;
+
+ table_two = (configure_table_t *)calloc(1, sizeof(configure_table_t));
+ table_two->table_name = table_name;
+ table_two->service_id = service_id;
+ table_two->hash_handle = hash_handle;
+ table_two->over_flag = false;
+ table_two->table_id_key = table_id;
+
+ table_two->get_hnode_sw_action_recur = two_get_hnode_sw_action;
+
+ table_two->drive_full_cfg_by_parent = two_drive_did_full_by_three;
+
+ table_two->maat_start_cb = two_maat_start_callback;
+ table_two->maat_update_cb= two_maat_update_callback;
+ table_two->maat_finish_cb= two_maat_finish_callback;
+ return table_two;
+}
+
+void three_destroy_hnode(void *data)
+{
+ three_config_hnode_t *hnode = (three_config_hnode_t *)data;
+ delete hnode;
+}
+
+static int64_t three_update_hnode_dset_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ three_config_hnode_t *hnode = (three_config_hnode_t *)data;
+ htable_privdata_t *priv = (htable_privdata_t *)arg;
+ int32_t ret;
+
+ if(hnode == NULL)
+ {
+ hnode = new __three_config_hnode();
+ if((ret = MESA_htable_add(priv->table->hash_handle, key, size, hnode)) < 0)
+ {
+ delete hnode;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s, MESA_htable_add failed: %d, ruleid: %u", priv->table->table_name, ret, priv->iprule.grule.rule_id);
+ return -1;
+ }
+ hnode->dsetid = priv->dsetid;
+ hnode->exist_before = false;
+ }
+
+ if(hnode->didset.find(priv->did) == hnode->didset.end())
+ {
+ hnode->didset[priv->did] = priv->did;
+ }
+
+ return 1;
+}
+
+int32_t three_update_hnode_dset(configure_table_t *table, int64_t dsetid, int64_t did)
+{
+ table_hash_key_t hash_key;
+ htable_privdata_t priv;
+ int64_t cb_ret;
+
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = 0;
+
+ memset(&priv, 0 ,sizeof(htable_privdata_t));
+ priv.table = table;
+ priv.dsetid = dsetid;
+ priv.did = did;
+
+ MESA_htable_search_cb(table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), three_update_hnode_dset_cb, (void*)&priv, &cb_ret);
+ return cb_ret;
+}
+
+int64_t three_get_hnode_sw_action_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ three_config_hnode_t *hnode = (three_config_hnode_t *)data;
+ swtable_state_t *sw_state = (swtable_state_t *)arg;
+
+ if(hnode == NULL || !hnode->exist_before)
+ {
+ return 0;
+ }
+
+ sw_state->switcher = hnode->sw_status;
+ sw_state->gmap_info = hnode->gmap_info;
+ return 1;
+}
+
+//���¶������ر���ÿ��DSET��DID���ϣ����ؿ���״̬
+int32_t three_get_hnode_sw_action(configure_table_t *table, int64_t dsetid, int64_t did, swtable_state_t *sw_state)
+{
+ table_hash_key_t hash_key;
+ int64_t cb_ret;
+
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = 0;
+
+ MESA_htable_search_cb(table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), three_get_hnode_sw_action_cb, (void*)sw_state, &cb_ret);
+ return cb_ret;
+}
+
+//���ο��ر��״�ȫ��������
+int64_t three_deal_config_incr_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ three_config_hnode_t *hnode = (three_config_hnode_t *)data;
+ htable_privdata_t *priv = (htable_privdata_t *)arg;
+ configure_table_t *table = priv->table;
+ int32_t ret;
+ swtable_state_t sw_state;
+
+ if(hnode == NULL)
+ {
+ hnode = new __three_config_hnode();
+ if((ret = MESA_htable_add(table->hash_handle, key, size, hnode)) < 0)
+ {
+ delete hnode;
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s, MESA_htable_add failed: %d, ruleid: %u", table->table_name, ret, priv->iprule.grule.rule_id);
+ pz_trans_statistic_count(table->service_id, table->table_id_key, 1, STAT_FIELD_DISP_FAIL);
+ return -1;
+ }
+ hnode->dsetid = priv->dsetid;
+ }
+ sw_state.switcher = hnode->sw_status = priv->did_switch;
+ sw_state.gmap_info = hnode->gmap_info = priv->gmap_info;
+ if(hnode->sw_status == SW_STAT_DEACTIVATE)
+ {
+ hnode->last_invalid = time(NULL);
+ }
+
+ configure_table_t *child = table->child;
+ map<int64_t, int64_t>::iterator iter;
+ int64_t did; //����two��ʱ��DID������onesw��ʱ��DSET
+ while(child != NULL)
+ {
+ if(child->child != NULL)
+ {
+ for(iter=hnode->didset.begin(); iter!=hnode->didset.end(); iter++)
+ {
+ did = iter->first;
+ child->drive_full_cfg_by_parent(child, hnode->dsetid, did, &sw_state);
+ }
+ }
+ else
+ {
+ child->drive_full_cfg_by_parent(child, hnode->dsetid, 0, &sw_state);
+ }
+ child = child->next;
+ }
+
+ hnode->exist_before = true;
+ return 0;
+}
+
+void three_maat_start_callback(int32_t update_type,void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+
+ maat_data->update_type = update_type;
+
+ if(maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_FULL))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pz_error: table %s recv another full config, restart.", maat_data->table->table_name);
+ exit(10);
+ }
+ if(!maat_data->table->over_flag && (update_type == MAAT_RULE_UPDATE_TYPE_INC))
+ {
+ maat_data->table->over_flag = true;
+ }
+}
+
+void three_maat_update_callback(int32_t table_id,const char* table_line,void* u_para)
+{
+ maat_callback_data_t *maat_data = (maat_callback_data_t *)u_para;
+ table_hash_key_t hash_key;
+ htable_privdata_t priv;
+ int64_t cb_ret, dsetid=0, did=0;
+ int32_t expr_type, match_method,is_hexbin,is_valid, service, action, limit_rate=0;
+ int64_t region_id, group_id;
+ char keywods[1024], user_region[4096];
+
+ cb_ret = sscanf(table_line, "%ld\t%ld\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%s",
+ &region_id, &group_id, keywods, &expr_type, &match_method, &is_hexbin, &is_valid, &action, &service, user_region);
+ if((cb_ret != 10) || fill_in_dsetid_did_limitid(user_region, &did, &dsetid, &limit_rate) || dsetid==0)
+ {
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, STAT_FIELD_RERROR);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_error: table %s invalid line: %s", maat_data->table->table_name, table_line);
+ return ;
+ }
+
+ memset(&priv, 0 ,sizeof(htable_privdata_t));
+ priv.table = maat_data->table;
+ priv.dsetid = dsetid;
+ priv.did = did;
+ priv.did_switch = is_valid?SW_STAT_ACTIVATE:SW_STAT_DEACTIVATE;
+ if(service_to_c3_servtype(service, (limit_rate/10)*10, &priv.gmap_info))
+ {
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, STAT_FIELD_RERROR);
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "pz_error: table %s service type error: %s", maat_data->table->table_name, table_line);
+ return ;
+ }
+ pz_trans_statistic_count(maat_data->table->service_id, maat_data->table->table_id_key, 1, is_valid?STAT_FIELD_RVALID:STAT_FIELD_RINVALID);
+
+ hash_key.service_id = maat_data->table->service_id;
+ hash_key.table_id = maat_data->table->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = 0;
+
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_INFO, MODULE_NAME, "pz_recv: table %s, region_id: %u, is_valid: %d, user_region: %s",
+ maat_data->table->table_name, region_id, is_valid, user_region);
+
+ pthread_rwlock_rdlock(&g_pgvalve_info.rwlock);
+ MESA_htable_search_cb(maat_data->table->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), three_deal_config_incr_cb, (void*)&priv, &cb_ret);
+ pthread_rwlock_unlock(&g_pgvalve_info.rwlock);
+}
+
+void three_maat_finish_callback(void* u_para)
+{
+ one_maat_finish_callback(u_para);
+}
+
+configure_table_t *new_table_instance_three(const char *table_name, int32_t service_id, int32_t table_id, MESA_htable_handle hash_handle)
+{
+ configure_table_t *table_three;
+
+ table_three = (configure_table_t *)calloc(1, sizeof(configure_table_t));
+ table_three->table_name = table_name;
+ table_three->service_id = service_id;
+ table_three->hash_handle = hash_handle;
+ table_three->over_flag = false;
+ table_three->table_id_key = table_id;
+
+ table_three->update_hnode_dset = three_update_hnode_dset;
+ table_three->get_hnode_sw_action_recur = three_get_hnode_sw_action;
+
+ table_three->maat_start_cb = three_maat_start_callback;
+ table_three->maat_update_cb= three_maat_update_callback;
+ table_three->maat_finish_cb= three_maat_finish_callback;
+ return table_three;
+}
+
+static int one_drive_full_iterate_cb(const uchar * key, uint size, void * data, void *user)
+{
+ table_hash_key_t *table_key = (table_hash_key_t *)key;
+ one_config_hnode_t *hnode;
+ configure_table_t *table = (configure_table_t *)user;
+
+ if(table_key->service_id!=table->service_id || table_key->table_id!=table->table_id_key)
+ {
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+ }
+
+ hnode = (one_config_hnode_t *)data;
+ hnode->disp_status = 0;
+ if(hnode->grule.action == GRULE_ACTION_ADD)
+ {
+ dispatch_config_to_c3(table->table_name, table->service_id, table->table_id_key, *hnode);
+ }
+ else
+ {
+ MESA_htable_del(table->hash_handle, key, size, one_destroy_hnode);
+ }
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+static int onesw_drive_full_iterate_cb(const uchar * key, uint size, void * data, void *user)
+{
+ table_hash_key_t *table_key = (table_hash_key_t *)key;
+ onesw_config_hnode_t *hnode;
+ configure_table_t *table = (configure_table_t *)user;
+ map<int64_t, one_config_hnode_t>::iterator iter;
+ swtable_state_t sw_state;
+
+ if(table_key->service_id!=table->service_id || table_key->table_id!=table->table_id_key)
+ {
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+ }
+
+ hnode = (onesw_config_hnode_t *)data;
+ if(!table->parent->get_hnode_sw_action_recur(table->parent, hnode->dsetid, hnode->did, &sw_state))
+ {
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+ }
+
+ for(iter=hnode->full.begin(); iter!=hnode->full.end(); )
+ {
+ if(iter->second.grule.action==GRULE_ACTION_DEL)
+ {
+ hnode->full.erase(iter++);
+ }
+ else
+ {
+ if(sw_state.switcher == SW_STAT_ACTIVATE)
+ {
+ iter->second.disp_status = 0;
+ iter->second.grule.srv_type = sw_state.gmap_info.serv_type;
+ iter->second.grule.rule_scope = sw_state.gmap_info.rule_scope;
+ dispatch_config_to_c3(table->table_name, table->service_id, table->table_id_key, iter->second);
+ }
+ iter++;
+ }
+ }
+
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+//�������½�����ֻ�·���Чȫ��
+void* thread_dispatch_full_config(void *arg)
+{
+ struct __tables_map_ref *table_map = (struct __tables_map_ref *)arg;
+ map<string, configure_table_t *>::iterator iter;
+ configure_table_t *table;
+ sigset_t sigmask;
+ int signo;
+
+ prctl(PR_SET_NAME, "pgvalve_dispfull");
+ sigemptyset(&sigmask);
+ sigaddset(&sigmask, SIGUSR1);
+ if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "pthread_sigmask failed.");
+ exit(1);
+ }
+
+ while(1)
+ {
+ if(sigwait(&sigmask, &signo) || signo != SIGUSR1)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "sigwait SIGUSR1 failed.");
+ sleep(10);
+ continue;
+ }
+
+ pthread_rwlock_wrlock(&g_pgvalve_info.rwlock);
+ clear_c3_first_status();
+ service_config_clear();
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "--------------Attention: reconnect to c3, drive all tables full start.--------------");
+ for(iter=table_map->tables_one.begin(); iter!=table_map->tables_one.end(); iter++)
+ {
+ table = iter->second;
+ if(table->parent != NULL) //onesw�ɸ�������
+ {
+ MESA_htable_iterate_bytime(table->hash_handle, ITERATE_TYPE_OLDEST_FIRST, onesw_drive_full_iterate_cb, (void *)table);
+ }
+ else
+ {
+ MESA_htable_iterate_bytime(table->hash_handle, ITERATE_TYPE_OLDEST_FIRST, one_drive_full_iterate_cb, (void *)table);
+ }
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "--------------Attention: reconnect to c3, drive all tables full over.--------------");
+ pthread_rwlock_unlock(&g_pgvalve_info.rwlock);
+ }
+
+ return NULL;
+}
+
diff --git a/src/pg_valve_deal.h b/src/pg_valve_deal.h
new file mode 100644
index 0000000..d506475
--- /dev/null
+++ b/src/pg_valve_deal.h
@@ -0,0 +1,141 @@
+#ifndef __PANGU_VAVLE_DEAL_H__
+#define __PANGU_VAVLE_DEAL_H__
+
+#include <iostream>
+#include <map>
+
+#include <MESA/Maat_rule.h>
+
+#include "pg_valve_c3.h"
+#include "pg_valve_tools.h"
+
+using namespace std;
+
+//IP���������
+#define REGION_TYPE_IP 1
+#define REGION_TYPE_FIND 2
+#define REGION_TYPE_POOL 3
+
+typedef enum __SSCANF_ERROR_NO
+{
+ SSCANF_OK=0,
+ SSCANF_ERROR_NUM,
+ SSCANF_ERROR_DID,
+ SSCANF_ERROR_DSETID,
+ SSCANF_ERROR_LIMIT,
+ SSCANF_ERROR_SERVICE,
+ SSCANF_ERROR_PROTOCOL,
+ SSCANF_ERROR_IP,
+ SSCANF_ERROR_TUPLE,
+ SSCANF_ERROR_RULE,
+}SSCANF_ERROR_NO_t;
+
+typedef enum __SW_STAT
+{
+ SW_STAT_NONE = 0,
+ SW_STAT_ACTIVATE = 1,
+ SW_STAT_DEACTIVATE = 2,
+}SW_STAT_t;
+
+typedef struct __grule_map_info
+{
+ int32_t serv_type;
+ int32_t rule_scope;
+}grule_map_info_t;
+
+typedef struct __table_hash_key
+{
+ int32_t service_id;
+ int32_t table_id;
+ int64_t dsetid;
+ int64_t did;
+}table_hash_key_t;
+
+typedef struct __swtable_state
+{
+ SW_STAT_t switcher;
+ grule_map_info_t gmap_info;
+}swtable_state_t;
+
+//�����صĶ������ر�
+//��������KEY: ServiceID+TableID+DSET+DID�����ҵ�DID��Ͻ����������ID
+//ȫ��or�����¼�����ʱ����:
+//��������
+typedef struct __onesw_config_hnode
+{
+ int64_t dsetid; //���������������أ�����Ϊ0
+ int64_t did;
+ map<int64_t, one_config_hnode_t> full; //KEY:cfg_id��DID����������Чȫ����
+}onesw_config_hnode_t;
+
+//��������KEY: ServiceID+TableID+DSET+DID���任TableID
+typedef struct __two_config_hnode
+{
+ int64_t dsetid; //���������������أ�����Ϊ0
+ int64_t did;
+ SW_STAT_t sw_status; //KEY: DID��VALUE: ����״̬
+ grule_map_info_t gmap_info;//�޸�����ʱ��Ч
+ time_t last_invalid;
+}two_config_hnode_t;
+
+//�������ر���KEY: ServiceID+TableID+DSET
+typedef struct __three_config_hnode
+{
+ int64_t dsetid;
+ SW_STAT_t sw_status; //DSET�Ŀ���
+ grule_map_info_t gmap_info;
+ bool exist_before;
+ map<int64_t, int64_t> didset;//KEY: DID��VALUE: ����ν
+ time_t last_invalid; //����ΪʧЧʱ�̵�ʱ�䣬����ʱ����ʱ��ɾ��Ԫ��
+}three_config_hnode_t;
+
+typedef struct __configure_table
+{
+ const char *table_name;
+ int32_t service_id;
+ int32_t table_id_key;
+ MESA_htable_handle hash_handle;
+ bool over_flag; //��ȫ���Ƿ����
+ int32_t action;
+ int32_t region_type;
+ int32_t table_id_maat;
+ int32_t statid_table;
+
+ //����ֵ��0-�ڵ㲻���ڣ�1-�ڵ����
+ int32_t (*get_hnode_sw_action_recur)(struct __configure_table *table, int64_t dsetid, int64_t did, swtable_state_t *result);
+ int32_t (*drive_full_cfg_by_parent)(struct __configure_table *table, int64_t dsetid, int64_t did, swtable_state_t *sw_state);
+ int32_t (*update_hnode_dset)(struct __configure_table *table, int64_t dsetid, int64_t did);
+
+ Maat_start_callback_t *maat_start_cb;
+ Maat_update_callback_t *maat_update_cb;
+ Maat_finish_callback_t *maat_finish_cb;
+
+ struct __configure_table *parent;//��ǰ���Ŀ��ر�����ʼ�����
+ struct __configure_table *child; //���ر��ĺ��ӱ�����ʼ�����
+ struct __configure_table *next; //���ر��ĺ��ӱ����ֵܱ��������Dz�ͬ����ĺ��ӱ�����ʼ�����
+}configure_table_t;
+
+typedef struct __htable_privdata
+{
+ configure_table_t *table;
+ int64_t dsetid; //three����oneswʱ����ֵ��ɶ?
+ int64_t did;
+ union{
+ one_config_hnode_t iprule; //���������
+ SW_STAT_t did_switch; //���ر�������
+ };
+ grule_map_info_t gmap_info; //���ر��·�C3��servtype
+}htable_privdata_t;
+
+void one_destroy_hnode(void *data);
+void two_destroy_hnode(void *data);
+void three_destroy_hnode(void *data);
+
+configure_table_t *new_table_instance_one(const char *table_name, int32_t service_id, int32_t table_id, int32_t region_type, MESA_htable_handle hash_handle);
+configure_table_t *new_table_instance_onesw(const char *table_name, int32_t service_id, int32_t table_id, int32_t region_type, MESA_htable_handle hash_handle);
+configure_table_t *new_table_instance_two(const char *table_name, int32_t service_id, int32_t table_id, MESA_htable_handle hash_handle);
+configure_table_t *new_table_instance_three(const char *table_name, int32_t service_id, int32_t table_id, MESA_htable_handle hash_handle);
+void* thread_dispatch_full_config(void *arg);
+
+#endif
+
diff --git a/src/pg_valve_maat.cpp b/src/pg_valve_maat.cpp
new file mode 100644
index 0000000..31039d4
--- /dev/null
+++ b/src/pg_valve_maat.cpp
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "pg_valve_maat.h"
+
+extern pgvavle_global_info_t g_pgvalve_info;
+
+//�޿���������ȫ���¼�
+
+//�п���������������ȫ���¼�
+
+int maat_start_config_table(configure_table_t *table, MaatService *maat_service)
+{
+ int ret;
+ maat_callback_data_t *maat_data;
+ Maat_feather_t feather = maat_service->get_maat_feather();
+
+ table->table_id_maat = Maat_table_register(feather, table->table_name);
+ if(table->table_id_maat < 0)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "Maat_table_register table %s failed.", table->table_name);
+ assert(0);
+ return -1;
+ }
+
+ maat_data = (maat_callback_data_t *)malloc(sizeof(maat_callback_data_t));
+ maat_data->table = table;
+ maat_data->update_type = 0;
+ maat_data->maat_service = maat_service;
+ ret = Maat_table_callback_register(feather, (short)table->table_id_maat, table->maat_start_cb, table->maat_update_cb, table->maat_finish_cb, maat_data);
+ if(ret != 1)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "Maat_table_callback_register table %s failed.", table->table_name);
+ assert(0);
+ return -2;
+ }
+ return 0;
+}
+
+long long MaatService::read_last_version(void)
+{
+ if(access(table_relate->version_file, R_OK))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_INFO, MODULE_NAME, "read_last_version %s failed: %s, using default version 0.", table_relate->version_file, strerror(errno));
+ return 0;
+ }
+ FILE *fp = fopen(table_relate->version_file, "r");
+ if(fp==NULL)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "read_last_version open %s failed: %s.", table_relate->version_file, strerror(errno));
+ assert(0);
+ return -1;
+ }
+ if(fscanf(fp, "%llu\n", &version) != 1)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "read_last_version fscanf %s failed: %s.", table_relate->version_file, strerror(errno));
+ fclose(fp);
+ assert(0);
+ return -1;
+ }
+ else
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "read_last_version %s success, version: %u.", table_relate->version_file, version);
+ }
+ fclose(fp);
+ return version;
+}
+
+int MaatService::store_latest_version(long long ver)
+{
+ char verbuf[48];
+
+ version = ver;
+ FILE *fp = fopen(table_relate->version_file, "w");
+ if(fp==NULL)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "Open version file %s failed: %s.", table_relate->version_file, strerror(errno));
+ return -1;
+ }
+
+ sprintf(verbuf, "%llu\n", version);
+ if(fwrite(verbuf, 1, strlen(verbuf), fp) != strlen(verbuf))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "fwrite version file %s failed: %s, version: %u.", table_relate->version_file, strerror(errno), version);
+ fclose(fp);
+ return -1;
+ }
+ fclose(fp);
+
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "store_latest_version %s success, version: %u.", table_relate->version_file, version);
+ return 0;
+}
+
+int MaatService::maat_feather_start(void)
+{
+ char tmp_buffer[1024];
+ int ret;
+
+ feather = Maat_feather(1, g_pgvalve_info.maat_table_info, g_pgvalve_info.log_runtime);
+ if(feather == NULL)
+ {
+ return -1;
+ }
+
+ snprintf(tmp_buffer, 1024, "%s/maat_stat_%s.log", g_pgvalve_info.root_log_dir, table_relate->instance_name);
+ ret = Maat_set_feather_opt(feather, MAAT_OPT_STAT_FILE_PATH, tmp_buffer, strlen(tmp_buffer)+1);
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_STAT_ON, NULL, 0);
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_PERF_ON, NULL, 0);
+
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, table_relate->instance_name, strlen(table_relate->instance_name)+1);
+ if(g_pgvalve_info.maat_source == MAAT_CONFIG_FILE)
+ {
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_FULL_CFG_DIR, table_relate->full_dir, strlen(table_relate->full_dir)+1);
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_INC_CFG_DIR, table_relate->incr_dir, strlen(table_relate->incr_dir)+1);
+ }
+ else
+ {
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_REDIS_IP, table_relate->redisip, strlen(table_relate->redisip)+1);
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_REDIS_PORT, &table_relate->redisport, sizeof(table_relate->redisport));
+ ret |= Maat_set_feather_opt(feather, MAAT_OPT_REDIS_INDEX, &table_relate->redis_index, sizeof(table_relate->redis_index));
+ }
+
+ if(ret || Maat_initiate_feather(feather) < 0)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "Maat_initiate_feather instance %s failed.", table_relate->instance_name);
+ return -2;
+ }
+
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "maat_feather_start instance %s success.", table_relate->instance_name);
+ return 0;
+}
+
diff --git a/src/pg_valve_maat.h b/src/pg_valve_maat.h
new file mode 100644
index 0000000..d6a134e
--- /dev/null
+++ b/src/pg_valve_maat.h
@@ -0,0 +1,51 @@
+#ifndef __PANGU_VALVE_H_MAAT_H__
+#define __PANGU_VALVE_H_MAAT_H__
+
+#include <MESA/MESA_htable.h>
+#include <MESA/field_stat2.h>
+#include <MESA/MESA_handle_logger.h>
+#include <MESA/Maat_rule.h>
+
+#include "pg_valve_tools.h"
+#include "pg_valve_deal.h"
+#include "pg_valve_main.h"
+
+#define MAAT_CONFIG_FILE 1
+#define MAAT_CONFIG_REDIS 2
+
+class MaatService
+{
+private:
+ struct maat_table_relation *table_relate;
+ Maat_feather_t feather;
+ long long version;
+
+public:
+ MaatService(struct maat_table_relation *table_relation)
+ {
+ table_relate = table_relation;
+ }
+ virtual ~MaatService(void)
+ {
+ Maat_burn_feather(feather);
+ }
+
+ Maat_feather_t get_maat_feather(void) {return feather;}
+
+ const char *get_instance_name(void) {return table_relate->instance_name;}
+ int store_latest_version(long long ver);
+ long long read_last_version(void);
+ int maat_feather_start(void);
+};
+
+typedef struct __maat_callback_data
+{
+ configure_table_t *table;
+ MaatService *maat_service;;
+ int update_type;
+}maat_callback_data_t;
+
+int maat_start_config_table(configure_table_t *table, MaatService *maat_service);
+
+#endif
+
diff --git a/src/pg_valve_main.cpp b/src/pg_valve_main.cpp
new file mode 100644
index 0000000..0931ede
--- /dev/null
+++ b/src/pg_valve_main.cpp
@@ -0,0 +1,926 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include <iostream>
+#include <map>
+#include <string>
+
+#include "load_table_info.hpp"
+
+#include "pg_valve_main.h"
+#include "pg_valve_maat.h"
+#include "pg_valve_stat.h"
+#include "pg_valve_consul.h"
+#include <MESA/wired_cfg.h>
+
+using namespace std;
+
+pgvavle_global_info_t g_pgvalve_info;
+map<int64_t, grule_map_info_t> g_map_service_grule;
+map<int32_t, int32_t> g_map_grule_fs2;
+bool g_valve_master=false;
+
+unsigned int get_ip_by_ifname(const char *ifname)
+{
+ int sockfd;
+ struct ifreq ifr;
+ unsigned int ip;
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (-1 == sockfd)
+ return INADDR_NONE;
+
+ strcpy(ifr.ifr_name,ifname);
+ if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0)
+ {
+ close(sockfd);
+ return INADDR_NONE;
+ }
+
+ ip = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr;
+ close(sockfd);
+ return ip;
+}
+
+static int32_t read_conf_and_init(void)
+{
+ char tmp_buf[256], tmp_logdir[256];
+
+ memset(&g_pgvalve_info, 0, sizeof(pgvavle_global_info_t));
+
+ //log init//
+ MESA_load_profile_string_def(PANGU_CONF_FILE, "LOG", "RUN_LOG_DIR", g_pgvalve_info.root_log_dir, sizeof(g_pgvalve_info.root_log_dir), "../log");
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "LOG", "RUN_LOG_LV", &g_pgvalve_info.log_level, 10);
+ sprintf(tmp_logdir, "%s/runtime_log", g_pgvalve_info.root_log_dir);
+ if(mkdir_according_path(tmp_logdir))
+ {
+ printf("mkdir %s failed: %s\n", g_pgvalve_info.root_log_dir, strerror(errno));
+ return -1;
+ }
+ snprintf(tmp_buf, 256, "%s/runtime.log", tmp_logdir);
+ g_pgvalve_info.log_runtime = MESA_create_runtime_log_handle(tmp_buf, g_pgvalve_info.log_level);
+ if(NULL==g_pgvalve_info.log_runtime)
+ {
+ return -1;
+ }
+ sprintf(tmp_logdir, "%s/statistic_log", g_pgvalve_info.root_log_dir);
+ if(mkdir_according_path(tmp_logdir))
+ {
+ printf("mkdir %s failed: %s\n", g_pgvalve_info.root_log_dir, strerror(errno));
+ return -1;
+ }
+ snprintf(tmp_buf, 256, "%s/statistic.log", tmp_logdir);
+ g_pgvalve_info.log_statistic = MESA_create_runtime_log_handle(tmp_buf, g_pgvalve_info.log_level);
+ if(NULL==g_pgvalve_info.log_statistic)
+ {
+ return -1;
+ }
+
+ MESA_load_profile_string_def(PANGU_CONF_FILE, "LOG", "ASMIS_PROC_NAME", g_pgvalve_info.asmis_appname, 64, "PANGU/valve");
+ MESA_load_profile_int_def(PANGU_CONF_FILE, "LOG", "ASMIS_HEART_INTERVAL", &g_pgvalve_info.asmis_heart_intvl, 10);
+ MESA_load_profile_string_def(PANGU_CONF_FILE, "LOG", "FS_STAT_APPNAME", g_pgvalve_info.appname, 64, "PANGU_VALVE");
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "LOG", "STATISTIC_INTERVAL", &g_pgvalve_info.statistic_period, 300);
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "LOG", "FS_STAT_TRIG", &g_pgvalve_info.fsstatid_trig, 0);
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "LOG", "FS_STAT_MODE", &g_pgvalve_info.fssprint_mode, 1);
+ MESA_load_profile_string_def(PANGU_CONF_FILE, "LOG", "FS_STAT_DST_IP", g_pgvalve_info.fs_dst_ip, 64, "10.172.128.2");
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "LOG", "FS_STAT_DST_PORT", &g_pgvalve_info.fs_dst_port, 8125);
+
+ if(0>MESA_load_profile_string_nodef(PANGU_CONF_FILE, "SYSTEM", "LOCAL_NET_NAME", tmp_buf, 64))
+ {
+ printf("[SYSTEM] CONSUL_LEADER_KEY not found.\n");
+ assert(0);
+ return -1;
+ }
+ int local_ip = get_ip_by_ifname(tmp_buf);
+ inet_ntop(AF_INET, &local_ip, g_pgvalve_info.local_ip, 64);
+
+ //ϵͳ����
+ if(MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "CONSUL_SWITCH", &g_pgvalve_info.consul_sw, 0) <0)
+ {
+ printf("[SYSTEM] CONSUL_SWITCH not found.\n");
+ assert(0);
+ return -1;
+ }
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "CONSUL_REQ_TIMEOUT", &g_pgvalve_info.http_timeout, 14);
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "CONSUL_LOCK_DELAY", &g_pgvalve_info.lock_delay, 10);
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "CONSUL_SESSION_TTL", &g_pgvalve_info.session_ttl, 30);
+ if(g_pgvalve_info.consul_sw && (0>MESA_load_profile_string_nodef(PANGU_CONF_FILE, "SYSTEM", "CONSUL_LEADER_KEY", g_pgvalve_info.leader_key, 128) || g_pgvalve_info.leader_key[0]==0))
+ {
+ printf("[SYSTEM] CONSUL_LEADER_KEY not found.\n");
+ assert(0);
+ return -1;
+ }
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "HASH_TABLE_SIZE", &g_pgvalve_info.hash_size, 8388608);
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "SW_HNODE_TIMEOUT_MIN", &g_pgvalve_info.sw_invalid_timeout, 2880);
+ g_pgvalve_info.sw_invalid_timeout *= 60; //2��
+
+ //Maat//
+ MESA_load_profile_string_def(PANGU_CONF_FILE, "SYSTEM", "MAAT_TABLE_INFO_PATH", g_pgvalve_info.maat_table_info, sizeof(g_pgvalve_info.maat_table_info), "./conf/maat_table_info.conf");
+ MESA_load_profile_int_def(PANGU_CONF_FILE, "SYSTEM", "MAAT_CONFIG_RECV_WAY", &g_pgvalve_info.maat_source, MAAT_CONFIG_REDIS);
+
+ MESA_load_profile_uint_def(PANGU_CONF_FILE, "SYSTEM", "SERVICE_TOPLIMIT_SW", &g_pgvalve_info.service_limit_sw, 0);
+ if(MESA_load_profile_string_nodef(PANGU_CONF_FILE, "SYSTEM", "C3_AUTH_DATA", g_pgvalve_info.authdata, 128) < 0)
+ {
+ assert(0);
+ return -1;
+ }
+ if(MESA_load_profile_string_nodef(PANGU_CONF_FILE, "SYSTEM", "C3_CCC_LISTS", g_pgvalve_info.ccclist, 128) < 0)
+ {
+ assert(0);
+ return -1;
+ }
+ pthread_rwlock_init(&g_pgvalve_info.rwlock, NULL);
+ return 0;
+}
+
+void wired_load_config(void)
+{
+ void *wired_handle = wired_cfg_create("PANGU_VALVE/cfg_pangu_valve", PANGU_CONF_FILE);
+ if(wired_cfg_init(wired_handle) != WCFG_RET_OK)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "wired_cfg_init %s failed.", PANGU_CONF_FILE);
+ }
+ wired_cfg_destroy(wired_handle);
+
+ wired_handle = wired_cfg_create("PANGU_VALVE/cfg_service_id_map", SERVICE_MAP_FILE);
+ if(wired_cfg_init(wired_handle) != WCFG_RET_OK)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "wired_cfg_init %s failed.", SERVICE_MAP_FILE);
+ }
+ wired_cfg_destroy(wired_handle);
+
+ wired_handle = wired_cfg_create("PANGU_VALVE/cfg_maat_info", MAAT_INFO_FILE);
+ if(wired_cfg_init(wired_handle) != WCFG_RET_OK)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "wired_cfg_init %s failed.", SERVICE_MAP_FILE);
+ }
+ wired_cfg_destroy(wired_handle);
+}
+
+bool instance_already_running(void)
+{
+ int fd;
+ struct flock flk;
+
+ fd = open(PANGU_LOCK_FILE, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if(fd < 0)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "instance_already_running: open file %s fail: %s.", strerror(errno));
+ return true;
+ }
+
+ flk.l_type = F_WRLCK;
+ flk.l_whence = SEEK_SET;
+ flk.l_start = flk.l_len = 0;
+
+ if(fcntl(fd, F_SETLK, &flk) < 0)
+ {
+ if(errno==EACCES || errno==EAGAIN)
+ {
+ return true;
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "instance_already_running: fcntl file %s fail: %s.", strerror(errno));
+ return true;
+ }
+ return false;
+}
+
+static int init_asmis_log_handle(const char *appname)
+{
+ int ret;
+
+ g_pgvalve_info.asmis_handle = asmis_log_Init(appname);;
+
+ ret = asmis_log_AppVer(g_pgvalve_info.asmis_handle, "2018-07-25T09:00:00", "20180725.1", "ConsulCluster");
+ ret |= asmis_log_RunStart(g_pgvalve_info.asmis_handle, 1);
+ return ret;
+}
+
+void htable_destroy_node(void *data)
+{
+ free(data);
+}
+
+static MESA_htable_handle init_and_create_htable(unsigned int slot_size, int expire_time, void (* data_free)(void *data))
+{
+ MESA_htable_create_args_t htable_args;
+
+ memset(&htable_args, 0, sizeof(MESA_htable_create_args_t));
+
+ htable_args.thread_safe = 1;
+ htable_args.recursive = 1;
+ htable_args.hash_slot_size = slot_size;
+ htable_args.max_elem_num = 10*slot_size;
+ //MESA_htable_iterate_bytime�ص����ٴε���serach/add�Ȳ���ʱ��HASH_ELIMINATE_ALGO_LRU��ı��ڲ����������±������ף�
+ htable_args.eliminate_type = HASH_ELIMINATE_ALGO_FIFO;
+ htable_args.expire_time = expire_time;
+ htable_args.data_free = data_free; //�ͷŽڵ��ڴ�
+
+ return MESA_htable_create(&htable_args, sizeof(MESA_htable_create_args_t));
+}
+
+void debug_print_tree(map<string, configure_table_t *> &top_debug)
+{
+ configure_table_t *parent, *tmp_parent;
+ configure_table_t *child, *tmp_child;
+ map<string, configure_table_t *>::iterator iter;
+ char buffer[1024];
+
+ for(iter=top_debug.begin(); iter!=top_debug.end(); iter++)
+ {
+ parent = iter->second;
+ child = parent->child;
+
+ while(child != NULL)
+ {
+ assert(child->parent == parent);
+ sprintf(buffer, "SW_TableTree: %s", iter->first.c_str());
+
+ tmp_parent = child;
+ while(tmp_parent != NULL)
+ {
+ tmp_child = tmp_parent->child;
+ sprintf(buffer+strlen(buffer), "-->%s", tmp_parent->table_name);
+
+ if(tmp_child != NULL) assert(tmp_parent == tmp_child->parent);
+ tmp_parent = tmp_child;
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "%s", buffer);
+
+ child = child->next;
+ }
+ }
+}
+
+bool is_table_three(configure_table_t *table)
+{
+ configure_table_t *next;
+
+ if(table->child == NULL)
+ {
+ return false;
+ }
+
+ next = table->child;
+ while(next != NULL)
+ {
+ if(next->child != NULL)
+ {
+ return true;
+ }
+ next = next->next;
+ }
+
+ return false;
+}
+
+int32_t fill_in_single_table_tree(char *line_content, struct config_table_relation *table, int32_t table_index)
+{
+ char region_type[64], table_three_name[64], table_two_name[64], table_onesw_name[64];
+ int ret;
+
+ ret = sscanf(line_content, "%[^ \t]%*[ \t]%s%*[ \t]%s%*[ \t]%u%*[ \t]%s",
+ table_three_name, table_two_name, table_onesw_name, &table->service_id, region_type);
+ if(ret != 5)
+ {
+ assert(0);
+ return -1;
+ }
+ if(!strcmp(table_three_name, "NULL"))
+ {
+ table->table_three_name[0] = '\0';
+ }
+ else if(sscanf(table_three_name, "%[^:]:%d", table->table_three_name, &table->table_id_three) != 2)
+ {
+ assert(0);
+ return -2;
+ }
+
+ if(!strcmp(table_two_name, "NULL"))
+ {
+ table->table_two_name[0] = '\0';
+ }
+ else if(sscanf(table_two_name, "%[^:]:%d", table->table_two_name, &table->table_id_two) != 2)
+ {
+ assert(0);
+ return -2;
+ }
+
+ if(sscanf(table_onesw_name, "%[^:]:%d", table->table_onesw_name, &table->table_id_onesw) != 2)
+ {
+ assert(0);
+ return -2;
+ }
+
+ if(!strcmp(region_type, "REGION_TYPE_IP"))
+ {
+ table->region_type = REGION_TYPE_IP;
+ }
+ else if(!strcmp(region_type, "REGION_TYPE_FIND"))
+ {
+ table->region_type = REGION_TYPE_FIND;
+ }
+ else if(!strcmp(region_type, "REGION_TYPE_POOL"))
+ {
+ table->region_type = REGION_TYPE_POOL;
+ }
+ else
+ {
+ return -2;
+ }
+
+ return 0;
+}
+
+int load_table_tree_info(struct config_table_relation **table_conifg_tree, int *num)
+{
+ LoadTableInfo<struct config_table_relation> load_tree(TABLES_TREE_FILE, fill_in_single_table_tree);
+
+ return load_tree.load_table_info(table_conifg_tree, num);
+}
+
+void set_child_to_parent(configure_table_t *parent, configure_table_t *child)
+{
+ if(parent->child == NULL)
+ parent->child = child;
+ else
+ {
+ configure_table_t *tmp = parent->child;
+ while(tmp->next != NULL)
+ tmp = tmp->next;
+ tmp->next = child;
+ }
+}
+
+int setup_sw_tables_relationship(map<string, configure_table_t *> &tables, map<string, configure_table_t *> &tables_sw, map<string, configure_table_t *> &tables_one)
+{
+ map<string, configure_table_t *> top_debug; //����TOP��
+ configure_table_t *ctable_three;
+ configure_table_t *ctable_two;
+ configure_table_t *ctable_onesw;
+ MESA_htable_handle hash_table;
+ struct config_table_relation *table_conifg_tree=NULL;
+ int table_num=0;
+
+ if(load_table_tree_info(&table_conifg_tree, &table_num))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "load_table_tree_info failed.");
+ return -1;
+ }
+
+ for(int i=0; i<table_num; i++)
+ {
+ ctable_three = ctable_two = NULL;
+
+ if(table_conifg_tree[i].table_three_name[0] != '\0')
+ {
+ if(tables.find(string(table_conifg_tree[i].table_three_name)) != tables.end())
+ {
+ ctable_three = tables[string(table_conifg_tree[i].table_three_name)];
+ assert(table_conifg_tree[i].table_id_three == ctable_three->table_id_key);
+ }
+ else
+ {
+ hash_table = init_and_create_htable(g_pgvalve_info.hash_size, 0, htable_destroy_node);
+ ctable_three = new_table_instance_three(table_conifg_tree[i].table_three_name, table_conifg_tree[i].service_id, table_conifg_tree[i].table_id_three, hash_table);
+ tables[string(table_conifg_tree[i].table_three_name)] = ctable_three;
+ tables_sw[string(table_conifg_tree[i].table_three_name)] = ctable_three;
+ top_debug[string(table_conifg_tree[i].table_three_name)] = ctable_three;
+ }
+ }
+
+ if(table_conifg_tree[i].table_two_name[0] != '\0')
+ {
+ if(tables.find(string(table_conifg_tree[i].table_two_name)) != tables.end())
+ {
+ ctable_two = tables[string(table_conifg_tree[i].table_two_name)];
+ assert(table_conifg_tree[i].table_id_two == ctable_two->table_id_key);
+ }
+ else
+ {
+ if(ctable_three != NULL)
+ {
+ hash_table = ctable_three->hash_handle;
+ }
+ else
+ {
+ hash_table = init_and_create_htable(g_pgvalve_info.hash_size, 0, htable_destroy_node);
+ }
+
+ ctable_two = new_table_instance_two(table_conifg_tree[i].table_two_name, table_conifg_tree[i].service_id, table_conifg_tree[i].table_id_two, hash_table);
+ tables[string(table_conifg_tree[i].table_two_name)] = ctable_two;
+ tables_sw[string(table_conifg_tree[i].table_two_name)] = ctable_two;
+
+ if(ctable_three != NULL)
+ {
+ ctable_two->parent = ctable_three;
+ set_child_to_parent(ctable_three, ctable_two);
+ }
+ else
+ {
+ top_debug[string(table_conifg_tree[i].table_two_name)] = ctable_two;
+ }
+ }
+ }
+
+ ctable_onesw = new_table_instance_onesw(table_conifg_tree[i].table_onesw_name, table_conifg_tree[i].service_id, table_conifg_tree[i].table_id_onesw, table_conifg_tree[i].region_type, hash_table);
+ tables[string(table_conifg_tree[i].table_onesw_name)] = ctable_onesw;
+ tables_one[string(table_conifg_tree[i].table_onesw_name)] = ctable_onesw;
+ if(ctable_two != NULL)
+ {
+ ctable_onesw->parent = ctable_two;
+ set_child_to_parent(ctable_two, ctable_onesw);
+ }
+ else
+ {
+ ctable_onesw->parent = ctable_three;
+ set_child_to_parent(ctable_three, ctable_onesw);
+ }
+ }
+
+ debug_print_tree(top_debug);
+ return 0;
+}
+
+int32_t fill_in_single_table_one(char *line_content, struct config_table_direct *table, int32_t table_index)
+{
+ char region_type[64], table_name[64];
+ int ret;
+
+ ret = sscanf(line_content, "%[^ \t]%*[ \t]%u%*[ \t]%s", table_name, &table->service_id, region_type);
+ if(ret != 3)
+ {
+ assert(0);
+ return -1;
+ }
+ if(sscanf(table_name, "%[^:]:%d", table->table_name, &table->table_id) != 2)
+ {
+ assert(0);
+ return -2;
+ }
+
+ if(!strcmp(region_type, "REGION_TYPE_IP"))
+ {
+ table->region_type = REGION_TYPE_IP;
+ }
+ else if(!strcmp(region_type, "REGION_TYPE_FIND"))
+ {
+ table->region_type = REGION_TYPE_FIND;
+ }
+ else if(!strcmp(region_type, "REGION_TYPE_POOL"))
+ {
+ table->region_type = REGION_TYPE_POOL;
+ }
+ else
+ {
+ return -2;
+ }
+ return 0;
+}
+
+int load_table_tree_one(struct config_table_direct **table_conifg_one, int *num)
+{
+ LoadTableInfo<struct config_table_direct> load_one(TABLES_ONE_FILE, fill_in_single_table_one);
+
+ return load_one.load_table_info(table_conifg_one, num);
+}
+
+int setup_direct_tables(map<string, configure_table_t *> &tables, map<string, configure_table_t *> &tables_one)
+{
+ configure_table_t *ctable_one;
+ MESA_htable_handle hash_table;
+ struct config_table_direct *table_conifg_direct=NULL;
+ int table_num=0;
+
+ if(load_table_tree_one(&table_conifg_direct, &table_num))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime,RLOG_LV_FATAL, MODULE_NAME, "load_table_tree_info failed.");
+ return -1;
+ }
+
+ for(int i=0; i<table_num; i++)
+ {
+ hash_table = init_and_create_htable(g_pgvalve_info.hash_size, 0, htable_destroy_node);
+ ctable_one = new_table_instance_one(table_conifg_direct[i].table_name, table_conifg_direct[i].service_id, table_conifg_direct[i].table_id, table_conifg_direct[i].region_type, hash_table);
+ assert(tables.find(string(table_conifg_direct[i].table_name)) == tables.end());
+ tables[string(table_conifg_direct[i].table_name)] = ctable_one;
+ tables_one[string(table_conifg_direct[i].table_name)] = ctable_one;
+ }
+
+ return 0;
+}
+
+int32_t fill_in_single_maat_instance(char *line_content, struct maat_table_relation *table, int32_t table_index)
+{
+ char maat_root[256], table_list[4096];
+ int ret, j;
+ char *ptmp, *save_ptr=NULL;
+
+ ret = sscanf(line_content, "%[^ \t]%*[ \t]%s%*[ \t]%s%*[ \t]%s%*[ \t]%u%*[ \t]%u%*[ \t]%s",
+ table->instance_name, maat_root, table->version_file,
+ table->redisip, &table->redisport, &table->redis_index, table_list);
+ if(ret != 7)
+ {
+ assert(0);
+ return -1;
+ }
+ snprintf(table->full_dir, 256, "%s/full/index", maat_root);
+ snprintf(table->incr_dir, 256, "%s/inc/index", maat_root);
+
+ table->table_num = 0;
+ for(ptmp = strtok_r(table_list, ";", &save_ptr); ptmp != NULL; ptmp = strtok_r(NULL, ";", &save_ptr))
+ {
+ if(table->table_num == 0)
+ {
+ table->tables_name = (char **)malloc(sizeof(void *));
+ }
+ else
+ {
+ table->tables_name = (char **)realloc(table->tables_name, (table->table_num + 1)*sizeof(void *));
+ }
+
+ for(j=0; j<table->table_num; j++)
+ {
+ if(!strcmp(table->tables_name[j], ptmp)) //�Ѿ�����
+ {
+ break;
+ }
+ }
+ if(j<table->table_num)
+ {
+ continue;
+ }
+ table->tables_name[table->table_num] = (char *)malloc(sizeof(char)*64);
+ snprintf(table->tables_name[table->table_num], 64, "%s", ptmp);
+ table->table_num++;
+ }
+ return 0;
+}
+
+int load_maat_info(struct maat_table_relation **maat_lists, int *num)
+{
+ LoadTableInfo<struct maat_table_relation> load_maat(MAAT_INFO_FILE, fill_in_single_maat_instance);
+
+ return load_maat.load_table_info(maat_lists, num);
+}
+
+int32_t get_gserv_type_fsid(int32_t gserv_type)
+{
+ if(g_map_grule_fs2.find(gserv_type) != g_map_grule_fs2.end())
+ {
+ return g_map_grule_fs2[gserv_type];
+ }
+
+ return -1;
+}
+
+int64_t service_map_key(int32_t service_id, int32_t limit_rate)
+{
+ int64_t service = service_id, limit = limit_rate;
+ return (limit<<32) | service;
+}
+
+int32_t service_to_c3_servtype(int32_t service_key, int32_t limit_rate, grule_map_info_t *gmap_info)
+{
+ int64_t key = service_map_key(service_key, limit_rate);
+
+ if(g_map_service_grule.find(key) != g_map_service_grule.end())
+ {
+ grule_map_info_t grule_info = g_map_service_grule[key];
+ gmap_info->serv_type = grule_info.serv_type;
+ gmap_info->rule_scope = grule_info.rule_scope;
+ return 0;
+ }
+ return -1;
+}
+
+int32_t fill_in_service_id_map(char *line_content, struct service_id_map *map_info, int32_t table_index)
+{
+ int ret;
+
+ ret = sscanf(line_content, "%d%*[ \t]%d%*[ \t]%d%*[ \t]%d%*[ \t]%lu",
+ &map_info->service_id, &map_info->limit_rate, &map_info->grule_info.serv_type, &map_info->grule_info.rule_scope, &map_info->max_limit);
+ if(ret != 5)
+ {
+ assert(0);
+ return -1;
+ }
+
+ return 0;
+}
+
+int load_service_map_info(void)
+{
+ struct service_id_map *map_lists;
+ int ret=0, num;
+ LoadTableInfo<struct service_id_map> load_serv_map(SERVICE_MAP_FILE, fill_in_service_id_map);
+ int64_t key;
+
+ if(load_serv_map.load_table_info(&map_lists, &num) < 0)
+ {
+ return -1;
+ }
+
+ for(int i=0; i<num; i++)
+ {
+ key = service_map_key(map_lists[i].service_id, map_lists[i].limit_rate);
+ if(g_map_service_grule.find(key) == g_map_service_grule.end())
+ {
+ g_map_service_grule[key] = map_lists[i].grule_info; //�����·��ķ���������G�������ͽ���ӳ��
+ g_map_grule_fs2[map_lists[i].grule_info.serv_type] = 0; //G����������FS����ӳ�䣬����ǰ�߽���ͳ��
+ ret |= service_grule_setup_hnode(map_lists[i].grule_info.serv_type, map_lists[i].max_limit);
+ }
+ }
+ free(map_lists);
+ return ret;
+}
+
+static int register_field_stat(map<string, configure_table_t *> &tables_one, map<string, configure_table_t *> &tables_sw,
+ const char *rootdir, const char *dstip, unsigned int dstport)
+{
+ char buffer[256], fsfile[256];
+ unsigned short fs_port=dstport;
+ const char *fs_colom_inc[STAT_INCR_NUM] ={"RECV", "ERROR", "RVALID", "RINVALID", "DISP_SUCC", "DISP_FAIL", "DISP_LIMIT"};
+ const char *fs_colom_exist[STAT_EXIST_NUM] ={"EXIST", "PENDING", "EACTIVE", "EINACTIVE"};
+ map<string, configure_table_t *>::iterator iter;
+ configure_table_t *table;
+ u_int32_t i;
+
+ snprintf(buffer, 256, "%s/field_stat2", rootdir);
+ if(mkdir_according_path(buffer))
+ {
+ printf("mkdir %s failed: %s\n", buffer, strerror(errno));
+ return -1;
+ }
+
+ snprintf(fsfile, 256, "%s/fsstat_clmb.log", buffer);
+ g_pgvalve_info.fsstat_handle = FS_create_handle();
+ FS_set_para(g_pgvalve_info.fsstat_handle, OUTPUT_DEVICE, fsfile, strlen(fsfile)+1);
+ FS_set_para(g_pgvalve_info.fsstat_handle, PRINT_MODE, &(g_pgvalve_info.fssprint_mode), sizeof(g_pgvalve_info.fssprint_mode));
+ FS_set_para(g_pgvalve_info.fsstat_handle, STAT_CYCLE, &(g_pgvalve_info.statistic_period), sizeof(g_pgvalve_info.statistic_period));
+
+ int value = 0;
+ FS_set_para(g_pgvalve_info.fsstat_handle, CREATE_THREAD, &value, sizeof(value));
+ value = 1;
+ FS_set_para(g_pgvalve_info.fsstat_handle, FLUSH_BY_DATE, &value, sizeof(value));
+
+ FS_set_para(g_pgvalve_info.fsstat_handle, APP_NAME, g_pgvalve_info.appname, strlen(g_pgvalve_info.appname)+1);
+ FS_set_para(g_pgvalve_info.fsstat_handle, STATS_SERVER_IP, dstip, strlen(dstip)+1);
+ FS_set_para(g_pgvalve_info.fsstat_handle, STATS_SERVER_PORT, &fs_port, sizeof(fs_port));
+
+ //FS_STAT��, IP���
+ for(iter=tables_one.begin(); iter!=tables_one.end(); iter++)
+ {
+ table = iter->second;
+ table->statid_table = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_LINE, FS_CALC_CURRENT, table->table_name);
+ if(table->statid_table < 0)
+ {
+ printf("FS_register FS_STYLE_LINE for %s fail.\n", table->table_name);
+ assert(0);
+ return -1;
+ }
+ }
+ g_pgvalve_info.statid_table_one = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_LINE, FS_CALC_CURRENT, "TOTAL_ONE");
+
+ //FS_STAT��, ���ر�
+ for(iter=tables_sw.begin(); iter!=tables_sw.end(); iter++)
+ {
+ table = iter->second;
+ table->statid_table = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_LINE, FS_CALC_CURRENT, table->table_name);
+ if(table->statid_table < 0)
+ {
+ printf("FS_register FS_STYLE_LINE for %s fail.\n", table->table_name);
+ assert(0);
+ return -1;
+ }
+ }
+ g_pgvalve_info.statid_table_sw = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_LINE, FS_CALC_CURRENT, "TOTAL_SW");
+
+ //FS_STAT��
+ for(i=0; i<STAT_INCR_NUM; i++)
+ {
+ g_pgvalve_info.statid_incr[i] = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, fs_colom_inc[i]);
+ }
+ for(i=0; i<STAT_EXIST_NUM; i++)
+ {
+ g_pgvalve_info.statid_exist[i] = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, fs_colom_exist[i]);
+ }
+
+ //FS_STAT����ͳ�ƣ�ͳ��ÿ��G�������͵���Ч��
+ map<int32_t, int32_t>::iterator iter_fs;
+ char item_name[64];
+ for(iter_fs=g_map_grule_fs2.begin(); iter_fs!=g_map_grule_fs2.end(); iter_fs++)
+ {
+ sprintf(item_name, "SERVICE_%u", iter_fs->first);
+ iter_fs->second = FS_register(g_pgvalve_info.fsstat_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, item_name);
+ }
+
+ FS_start(g_pgvalve_info.fsstat_handle);
+ return 0;
+}
+
+void* thread_consul_status(void *arg)
+{
+ const char *session_id = (char *)arg;
+ bool retry;
+ time_t start_time, end_time;
+
+ while(1)
+ {
+ start_time = time(NULL);
+ retry = false;
+retry_lock:
+ if(!consul_try_get_lock(session_id, g_pgvalve_info.leader_key, g_pgvalve_info.local_ip, g_pgvalve_info.http_timeout))
+ {
+ if(g_valve_master) //�Ѿ���master�˲���Ҫ���ԣ�������Ȼʧ�ܾ����������ͷ���
+ {
+ if(!retry)
+ {
+ retry = true;
+ goto retry_lock;
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "consul_try_get_lock failed, restart.");
+ exit(20);
+ }
+ }
+ else if(!g_valve_master)
+ {
+ g_valve_master = true;
+ }
+
+ retry = false;
+retry_session:
+ if(!consul_renew_session(session_id, g_pgvalve_info.http_timeout)) //slaveҲ��Ҫˢ��session
+ {
+ if(!retry)
+ {
+ retry = true;
+ goto retry_session;
+ }
+ else
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "consul_renew_session failed, restart.");
+ exit(20);
+ }
+ }
+
+ end_time = time(NULL);
+ if(start_time + g_pgvalve_info.session_ttl >= end_time)
+ {
+ sleep((g_pgvalve_info.session_ttl - (end_time-start_time))/2);
+ }
+ }
+
+ return NULL;
+}
+
+void* thread_asmis_log(void *arg)
+{
+ while(1)
+ {
+ sleep(g_pgvalve_info.asmis_heart_intvl);
+ asmis_log_HeartBeat(g_pgvalve_info.asmis_handle, "pangu_valve is running");
+ }
+ return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+ struct maat_table_relation *g_table_maat_lists=NULL;
+ int g_table_maat_num;
+ map<string, configure_table_t *> tables; //���б�
+ map<string, configure_table_t *> tables_one; //���б�
+ map<string, configure_table_t *> tables_sw; //���б�
+ pthread_t thread_desc;
+ pthread_attr_t attr;
+ char session_id[128];
+
+ wired_load_config();
+ if(read_conf_and_init() || init_asmis_log_handle(g_pgvalve_info.asmis_appname))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "read_conf_and_init/init_asmis_log_handle fail.");
+ return -1;
+ }
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&thread_desc, &attr, thread_asmis_log, NULL);
+ if(g_pgvalve_info.consul_sw)
+ {
+ if(!consul_create_session(g_pgvalve_info.lock_delay, g_pgvalve_info.session_ttl, session_id, 128, g_pgvalve_info.log_runtime))
+ {
+ printf("consul_create_session failed.\n");
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "consul_create_session failed.");
+ exit(20);
+ }
+ pthread_create(&thread_desc, &attr, thread_consul_status, (void *)session_id);
+ while(!g_valve_master)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_DEBUG, MODULE_NAME, "pangu_valve waiting to be master.");
+ sleep(4);
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "pangu_valve elected as master! session_id: %s.", session_id);
+ }
+ else if(instance_already_running())
+ {
+ printf("There is another instance already running, only one instance can run at the same time.\n");
+ exit(20);
+ }
+
+ g_pgvalve_info.htable_stat_log = init_and_create_htable(256, 0, NULL);
+ g_pgvalve_info.htable_stat_serv = init_and_create_htable(256, 0, NULL);
+
+ if(load_service_map_info())
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "load_service_map_info fail.");
+ return -1;
+ }
+
+ if(load_maat_info(&g_table_maat_lists, &g_table_maat_num))
+ {
+ return -1;
+ }
+ if(setup_sw_tables_relationship(tables, tables_sw, tables_one))
+ {
+ return -2;
+ }
+ if(setup_direct_tables(tables, tables_one))
+ {
+ return -3;
+ }
+
+ assert(tables.size() == tables_one.size()+tables_sw.size());
+ if(register_field_stat(tables_one, tables_sw, g_pgvalve_info.root_log_dir, g_pgvalve_info.fs_dst_ip, g_pgvalve_info.fs_dst_port))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "register_field_stat fail.");
+ return -1;
+ }
+
+ struct __tables_map_ref table_map = {tables_one, tables_sw};
+ if(pthread_create(&thread_desc, &attr, thread_dispatch_full_config, (void *)&table_map))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "pthread_create(): %s", strerror(errno));
+ return -1;
+ }
+ if(!global_init_grule_handle(g_pgvalve_info.authdata, strlen(g_pgvalve_info.authdata), g_pgvalve_info.ccclist, thread_desc))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "global_init_grule_handle fail.");
+ return -1;
+ }
+
+ MaatService **maat_service = (MaatService **)malloc(g_table_maat_num * sizeof(void *));
+ for(int i=0; i<g_table_maat_num; i++)
+ {
+ maat_service[i] = new MaatService(&g_table_maat_lists[i]);
+ if(maat_service[i] == NULL)
+ {
+ assert(0);
+ return -1;
+ }
+ if(maat_service[i]->maat_feather_start() < 0)
+ {
+ assert(0);
+ return -1;
+ }
+
+ for(int j=0; j<g_table_maat_lists[i].table_num; j++)
+ {
+ assert(tables.find(g_table_maat_lists[i].tables_name[j]) != tables.end());
+ configure_table_t *table = tables[g_table_maat_lists[i].tables_name[j]];
+ if(maat_start_config_table(table, maat_service[i]))
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "maat_start_config_table_%s %s:%d failed.", maat_service[i]->get_instance_name(), table->table_name, table->table_id_key);
+ return -2;
+ }
+ else
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "maat_start_config_table_%s %s:%d success.", maat_service[i]->get_instance_name(), table->table_name, table->table_id_key);
+ }
+ }
+ }
+ MESA_HANDLE_RUNTIME_LOGV2(g_pgvalve_info.log_runtime, RLOG_LV_FATAL, MODULE_NAME, "pangu_valve starts all tables full config over.\n");
+
+ time_t now, remain;
+ while(1)
+ {
+ now = time(NULL);
+ remain = g_pgvalve_info.statistic_period - (now % g_pgvalve_info.statistic_period);
+ sleep(remain);
+
+ valve_statistic_log_output(tables_one, tables_sw);
+ }
+ return 0;
+}
+
diff --git a/src/pg_valve_main.h b/src/pg_valve_main.h
new file mode 100644
index 0000000..e83e9e7
--- /dev/null
+++ b/src/pg_valve_main.h
@@ -0,0 +1,134 @@
+#ifndef __PANGU_VAVLE_MAIN_H__
+#define __PANGU_VAVLE_MAIN_H__
+
+#include <MESA/MESA_htable.h>
+#include <MESA/field_stat2.h>
+#include <MESA/MESA_handle_logger.h>
+#include <MESA/Maat_rule.h>
+#include <MESA/asmis_log.h>
+#include <MESA/MESA_prof_load.h>
+
+#include "pg_valve_tools.h"
+#include "pg_valve_stat.h"
+#include "pg_valve_deal.h"
+
+#define PANGU_CONF_FILE "./conf/pangu_valve.conf"
+#define PANGU_LOCK_FILE "/tmp/pangu_valve_lock"
+
+#define TABLES_ONE_FILE "./conf/table_info/table_info_one.conf"
+#define TABLES_TREE_FILE "./conf/table_info/table_info_tree.conf"
+#define MAAT_INFO_FILE "./conf/table_info/maat_info.conf"
+#define SERVICE_MAP_FILE "./conf/table_info/service_id_map.conf"
+
+#define MODULE_NAME "PG_VALVE"
+
+#define MAX_PATH_LEN 256
+
+struct config_table_direct
+{
+ char table_name[64];
+ int32_t service_id;
+ int32_t table_id; //Ψһֵ��������ϣ��key�������ش�Magellan��־
+ int32_t region_type; //һ��IP��������
+};
+
+struct config_table_relation{
+ char table_three_name[64];
+ char table_two_name[64];
+ char table_onesw_name[64];
+ int32_t service_id;
+ int32_t table_id_three;
+ int32_t table_id_two;
+ int32_t table_id_onesw;
+ int32_t region_type; //һ��IP��������
+};
+
+struct maat_table_relation{
+ char instance_name[64];
+ char full_dir[256];
+ char incr_dir[256];
+ char version_file[256];
+ char redisip[128];
+ int redisport;
+ int redis_index;
+ char **tables_name;
+ int table_num;
+};
+
+struct service_id_map
+{
+ int32_t service_id;
+ int32_t limit_rate;
+ grule_map_info_t grule_info;
+ u_int64_t max_limit;
+};
+
+typedef struct __pgvavle_global_info
+{
+ //MaatRedis//
+ char maat_table_info[MAX_PATH_LEN];
+ char redis_ip[64];
+ int redis_port;
+ int maat_source;
+
+ //���ݽṹ
+ unsigned int hash_size;
+ unsigned int sw_invalid_timeout; //���ر�Ԫ��ʧЧ���ϣ����̭ʱ��
+ MESA_htable_handle htable_stat_log; //�Ա�Ϊ��λͳ�����������ͳ����־
+ MESA_htable_handle htable_stat_serv;//ͳ��service����Ч�����������������ޣ�
+
+ //����
+ char leader_key[128];
+ char local_ip[64];
+ unsigned int consul_sw;
+ unsigned int http_timeout;
+ unsigned int lock_delay;
+ unsigned int session_ttl;
+
+ //C3
+ char authdata[128];
+ char ccclist[128];
+ unsigned int service_limit_sw;
+ pthread_rwlock_t rwlock;
+
+ //log//
+ unsigned int log_level;
+ int asmis_heart_intvl;
+ char root_log_dir[MAX_PATH_LEN];
+ char asmis_appname[128];
+ void *log_runtime;
+ void *log_statistic;
+ void *asmis_handle;
+ screen_stat_handle_t fsstat_handle;
+ char fs_dst_ip[64];
+ char appname[64];
+ int statid_table_one;
+ int statid_table_sw;
+ int statid_exist[STAT_EXIST_NUM];
+ int statid_incr[STAT_INCR_NUM];
+ unsigned int statistic_period;
+ unsigned int fsstatid_trig;
+ unsigned int fssprint_mode;
+ unsigned int fs_dst_port;
+}pgvavle_global_info_t;
+
+bool is_table_three(configure_table_t *table);
+
+struct __tables_map_ref
+{
+ map<string, configure_table_t *> &tables_one; //���б�
+ map<string, configure_table_t *> &tables_sw; //���б�
+};
+
+typedef struct __iterator_table_priv
+{
+ configure_table_t *table;
+ statistic_exist_t *stat_out;
+}iterator_table_priv_t;
+
+int32_t service_to_c3_servtype(int32_t service_key, int32_t limit_rate, grule_map_info_t *gmap_info);
+int32_t get_gserv_type_fsid(int32_t gserv_type);
+void valve_statistic_log_output(map<string, configure_table_t *> &tables_one, map<string, configure_table_t *> &tables_sw);
+
+#endif
+
diff --git a/src/pg_valve_stat.cpp b/src/pg_valve_stat.cpp
new file mode 100644
index 0000000..63741c6
--- /dev/null
+++ b/src/pg_valve_stat.cpp
@@ -0,0 +1,490 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/prctl.h>
+
+#include <MESA/MESA_htable.h>
+
+#include "pg_valve_main.h"
+#include "pg_valve_stat.h"
+
+extern pgvavle_global_info_t g_pgvalve_info;
+
+static int service_config_clear_iterator(const uchar * key, uint size, void * data, void *user)
+{
+ stat_service_hnode_t *hnode = (stat_service_hnode_t *)data;
+ hnode->cur_num = 0;
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+void service_config_clear(void)
+{
+ MESA_htable_iterate_bytime(g_pgvalve_info.htable_stat_serv, ITERATE_TYPE_OLDEST_FIRST, service_config_clear_iterator, NULL);
+}
+
+static int service_config_limit_iterator(const uchar * key, uint size, void * data, void *user)
+{
+ stat_service_hnode_t *hnode = (stat_service_hnode_t *)data;
+ int32_t gserv_type = *(int32_t *)key;
+
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, get_gserv_type_fsid(gserv_type), 0, FS_OP_SET, hnode->cur_num);
+ }
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+static long service_grule_setup_hnode_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ stat_service_hnode_t *hnode = (stat_service_hnode_t *)data;
+ int ret;
+ u_int64_t max_num = *(u_int64_t *)arg;
+
+ if(hnode == NULL)
+ {
+ hnode = (stat_service_hnode_t *)calloc(1, sizeof(stat_service_hnode_t));
+ if((ret = MESA_htable_add(g_pgvalve_info.htable_stat_serv, key, size, hnode)) < 0)
+ {
+ free(hnode);
+ return -1;
+ }
+ }
+
+ hnode->max_num = max_num;
+ return 0;
+}
+
+int service_grule_setup_hnode(int32_t serv_type, u_int64_t max_num)
+{
+ long cb_ret;
+
+ MESA_htable_search_cb(g_pgvalve_info.htable_stat_serv, (unsigned char *)&serv_type, sizeof(serv_type), service_grule_setup_hnode_cb, &max_num, &cb_ret);
+ return (cb_ret==0)?0:-1;
+}
+
+static long service_grule_statistic_count_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ stat_service_hnode_t *hnode = (stat_service_hnode_t *)data;
+ stat_service_priv_t *serv_priv = (stat_service_priv_t *)arg;
+
+ if(hnode == NULL)
+ {
+ assert(0);
+ }
+
+ switch(serv_priv->type)
+ {
+ case STAT_SERVICE_ADD:
+ hnode->cur_num += serv_priv->log_num;
+ break;
+ case STAT_SERVICE_DEL:
+ assert(hnode->cur_num >= serv_priv->log_num);
+ hnode->cur_num -= serv_priv->log_num;
+ break;
+ default: break;
+ }
+
+ return 0;
+}
+
+void service_grule_statistic_count(int32_t serv_type, int32_t log_num, STAT_SERVICE_TYPE_t stat_type)
+{
+ stat_service_priv_t serv_priv;
+ long cb_ret;
+
+ serv_priv.log_num = log_num;
+ serv_priv.type = stat_type;
+ MESA_htable_search_cb(g_pgvalve_info.htable_stat_serv, (unsigned char *)&serv_type, sizeof(serv_type), service_grule_statistic_count_cb, &serv_priv, &cb_ret);
+}
+
+static long service_grule_reach_limit_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ stat_service_hnode_t *hnode = (stat_service_hnode_t *)data;
+
+ return (hnode==NULL || hnode->cur_num<hnode->max_num)?0:1;
+}
+
+bool service_grule_reach_limit(int32_t serv_type)
+{
+ long cb_ret;
+
+ MESA_htable_search_cb(g_pgvalve_info.htable_stat_serv, (unsigned char *)&serv_type, sizeof(serv_type), service_grule_reach_limit_cb, NULL, &cb_ret);
+ return (cb_ret==1);
+}
+
+static long pz_trans_statistic_count_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ statistic_incr_t *hnode = (statistic_incr_t *)data;
+ stat_table_priv_t *htable_priv = (stat_table_priv_t *)arg;
+ int ret;
+
+ if(hnode == NULL)
+ {
+ hnode = (statistic_incr_t *)calloc(1, sizeof(statistic_incr_t));
+ if((ret = MESA_htable_add(g_pgvalve_info.htable_stat_log, key, size, hnode)) < 0)
+ {
+ free(hnode);
+ return -1;
+ }
+ }
+
+ switch(htable_priv->type)
+ {
+ case STAT_FIELD_RECV:
+ break;
+ case STAT_FIELD_RERROR:
+ case STAT_FIELD_RVALID:
+ case STAT_FIELD_RINVALID:
+ hnode->num[htable_priv->type] += htable_priv->log_num;
+ hnode->num[STAT_FIELD_RECV] += htable_priv->log_num;
+ break;
+
+ default:
+ hnode->num[htable_priv->type] += htable_priv->log_num;
+ break;
+ }
+
+ return 0;
+}
+
+void pz_trans_statistic_count(int32_t service_id, int32_t table_id, int32_t log_num, STAT_FIELD_INCR_t type)
+{
+ stat_table_key_t hash_key;
+ stat_table_priv_t htable_priv;
+ long cb_ret = 0;
+
+ hash_key.service_id = service_id;
+ hash_key.table_id = table_id;
+
+ htable_priv.log_num = log_num;
+ htable_priv.type = type;
+
+ MESA_htable_search_cb(g_pgvalve_info.htable_stat_log, (unsigned char *)&hash_key, sizeof(stat_table_key_t), pz_trans_statistic_count_cb, (void*)&htable_priv, &cb_ret);
+}
+
+static long table_statistic_incr_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ statistic_incr_t *hnode = (statistic_incr_t *)data;
+ statistic_incr_t *statistic_incr = (statistic_incr_t *)arg;
+
+ if(hnode != NULL)
+ {
+ for(int i=0;i<STAT_INCR_NUM; i++)
+ {
+ statistic_incr->num[i] = hnode->num[i];
+ hnode->num[i] = 0;
+ }
+ }
+
+ return 0;
+}
+
+static int table_onesw_exist_iterate(const uchar * key, uint size, void * data, void *user)
+{
+ table_hash_key_t *table_key = (table_hash_key_t *)key;
+ iterator_table_priv_t *iterator_priv = (iterator_table_priv_t *)user;
+ swtable_state_t sw_state;
+
+ if(table_key->service_id==iterator_priv->table->service_id && table_key->table_id==iterator_priv->table->table_id_key)
+ {
+ onesw_config_hnode_t *hnode = (onesw_config_hnode_t *)data;
+
+ iterator_priv->stat_out->num[STAT_FIELD_EXITS] += hnode->full.size();
+ if(!iterator_priv->table->parent->get_hnode_sw_action_recur(iterator_priv->table->parent, table_key->dsetid, table_key->did, &sw_state))
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_PENDING] += hnode->full.size();
+ }
+ else if(sw_state.switcher==SW_STAT_DEACTIVATE)
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_EINACTIVE] += hnode->full.size();
+ }
+ else
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_EACTIVE] += hnode->full.size();
+ }
+ }
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+static int64_t table_three_erase_did_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ three_config_hnode_t *hnode = (three_config_hnode_t *)data;
+ int64_t did = *(int64_t *)arg;
+
+ if(hnode->didset.find(did) != hnode->didset.end())
+ {
+ hnode->didset.erase(did);
+ }
+ return 0;
+}
+
+void table_three_erase_did(configure_table_t *table_three, int64_t dsetid, int64_t did)
+{
+ table_hash_key_t hash_key;
+ long cb_ret;
+
+ hash_key.service_id = table_three->service_id;
+ hash_key.table_id = table_three->table_id_key;
+ hash_key.dsetid = dsetid;
+ hash_key.did = 0;
+
+ MESA_htable_search_cb(table_three->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), table_three_erase_did_cb, &did, &cb_ret);
+}
+
+static int table_two_exist_iterate(const uchar * key, uint size, void * data, void *user)
+{
+ table_hash_key_t *table_key = (table_hash_key_t *)key;
+ iterator_table_priv_t *iterator_priv = (iterator_table_priv_t *)user;
+
+ if(table_key->service_id==iterator_priv->table->service_id && table_key->table_id==iterator_priv->table->table_id_key)
+ {
+ two_config_hnode_t *hnode = (two_config_hnode_t *)data;
+
+ if(hnode->sw_status == SW_STAT_DEACTIVATE && (time(NULL)-hnode->last_invalid)>=g_pgvalve_info.sw_invalid_timeout)
+ {
+ if(iterator_priv->table->parent != NULL)
+ {
+ table_three_erase_did(iterator_priv->table->parent, hnode->dsetid, hnode->did);
+ }
+ MESA_htable_del(iterator_priv->table->hash_handle, key, size, two_destroy_hnode);
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+ }
+
+ iterator_priv->stat_out->num[STAT_FIELD_EXITS] += 1;
+ if(hnode->sw_status == SW_STAT_ACTIVATE)
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_EACTIVE] += 1;
+ }
+ else
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_EINACTIVE] += 1;
+ }
+ }
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+static int64_t two_hnode_active_exist_cb(void *data, const uchar *key, uint size, void *arg)
+{
+ two_config_hnode_t *hnode = (two_config_hnode_t *)data;
+
+ if(hnode != NULL && hnode->sw_status==SW_STAT_ACTIVATE)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+static bool table_two_active_node_exist(configure_table_t *table_two_maybe, three_config_hnode_t *hnode)
+{
+ map<int64_t, int64_t>::iterator iter;
+ long two_active;
+ table_hash_key_t hash_key;
+
+ while(table_two_maybe != NULL)
+ {
+ if(table_two_maybe->child != NULL)
+ {
+ for(iter=hnode->didset.begin(); iter!=hnode->didset.end(); iter++)
+ {
+ hash_key.service_id = table_two_maybe->service_id;
+ hash_key.table_id = table_two_maybe->table_id_key;
+ hash_key.dsetid = hnode->dsetid;
+ hash_key.did = iter->first;
+
+ MESA_htable_search_cb(table_two_maybe->hash_handle, (unsigned char *)&hash_key, sizeof(table_hash_key_t), two_hnode_active_exist_cb, NULL, &two_active);
+ if(two_active)
+ {
+ return true;
+ }
+ }
+ }
+ table_two_maybe = table_two_maybe->next;
+ }
+
+ return false;
+}
+
+static int table_three_exist_iterate(const uchar * key, uint size, void * data, void *user)
+{
+ table_hash_key_t *table_key = (table_hash_key_t *)key;
+ iterator_table_priv_t *iterator_priv = (iterator_table_priv_t *)user;
+
+ if(table_key->service_id==iterator_priv->table->service_id && table_key->table_id==iterator_priv->table->table_id_key)
+ {
+ three_config_hnode_t *hnode = (three_config_hnode_t *)data;
+
+ if(!hnode->exist_before)
+ {
+ //�л�Ծ�������ڵ���ڣ��Ͳ���ɾ�������������ڵ���Ч�������޷���֪did����
+ if(!table_two_active_node_exist(iterator_priv->table->child, hnode))
+ {
+ MESA_htable_del(iterator_priv->table->hash_handle, key, size, three_destroy_hnode);
+ }
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+ }
+
+ if(hnode->sw_status==SW_STAT_DEACTIVATE && (time(NULL)-hnode->last_invalid)>=g_pgvalve_info.sw_invalid_timeout
+ && !table_two_active_node_exist(iterator_priv->table->child, hnode))
+ {
+ MESA_htable_del(iterator_priv->table->hash_handle, key, size, three_destroy_hnode);
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+ }
+
+ iterator_priv->stat_out->num[STAT_FIELD_EXITS] += 1;
+ if(hnode->sw_status == SW_STAT_ACTIVATE)
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_EACTIVE] += 1;
+ }
+ else
+ {
+ iterator_priv->stat_out->num[STAT_FIELD_EINACTIVE] += 1;
+ }
+ }
+ return ITERATE_CB_RET_CONTINUE_FLAG;
+}
+
+void valve_statistic_log_output(map<string, configure_table_t *> &tables_one, map<string, configure_table_t *> &tables_sw)
+{
+ statistic_incr_t statistic_incr, statistic_incr_tt;
+ statistic_exist_t statistic_exist, statistic_exist_tt;
+ map<string, configure_table_t *>::iterator iter;
+ configure_table_t *table;
+ stat_table_key_t hash_key;
+ iterator_table_priv_t iterator_priv;
+ long cb_ret;
+
+ MESA_handle_runtime_log(g_pgvalve_info.log_statistic, RLOG_LV_FATAL, "STAT_INFO_TABLE", "---------------------------------------------------------------------------------------------------------------------------------");
+ //��SW��ͳ�ƣ��ܹ�ˢ����״̬
+ memset(&statistic_incr_tt, 0, sizeof(statistic_incr_t));
+ memset(&statistic_exist_tt, 0, sizeof(statistic_exist_t));
+ for(iter=tables_sw.begin(); iter!=tables_sw.end(); iter++)
+ {
+ memset(&statistic_incr, 0, sizeof(statistic_incr_t));
+ memset(&statistic_exist, 0, sizeof(statistic_exist_t));
+
+ table = iter->second;
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ MESA_htable_search_cb(g_pgvalve_info.htable_stat_log, (uchar*)&hash_key, sizeof(stat_table_key_t), table_statistic_incr_cb, (void *)&statistic_incr, &cb_ret);
+ iterator_priv.table = table;
+ iterator_priv.stat_out = &statistic_exist;
+ if(is_table_three(table))
+ {
+ MESA_htable_iterate_bytime(table->hash_handle, ITERATE_TYPE_OLDEST_FIRST, table_three_exist_iterate, (void *)&iterator_priv);
+ }
+ else
+ {
+ MESA_htable_iterate_bytime(table->hash_handle, ITERATE_TYPE_OLDEST_FIRST, table_two_exist_iterate, (void *)&iterator_priv);
+ }
+
+ MESA_handle_runtime_log(g_pgvalve_info.log_statistic, RLOG_LV_FATAL, "STAT_INFO_TABLE_SWT",
+ "%-20s-->RECV: %4llu, ERROR: %4llu, RVALID: %4llu, RINVALID: %4llu, DISP_SUCC: %4llu, DISP_FAIL: %4llu, DISP_LIMIT: %4llu; EXIST: %4llu, EACTIVE: %4llu, EINACTIVE: %4llu, PENDING: %4llu",
+ table->table_name, statistic_incr.num[STAT_FIELD_RECV], statistic_incr.num[STAT_FIELD_RERROR], statistic_incr.num[STAT_FIELD_RVALID],
+ statistic_incr.num[STAT_FIELD_RINVALID], statistic_incr.num[STAT_FIELD_DISP_SUCC], statistic_incr.num[STAT_FIELD_DISP_FAIL], statistic_incr.num[STAT_FIELD_DISP_LIMIT],
+ statistic_exist.num[STAT_FIELD_EXITS], statistic_exist.num[STAT_FIELD_EACTIVE], statistic_exist.num[STAT_FIELD_EINACTIVE], statistic_exist.num[STAT_FIELD_PENDING]);
+
+ for(int j=0; j<STAT_INCR_NUM; j++)
+ {
+ statistic_incr_tt.num[j] += statistic_incr.num[j];
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, table->statid_table, g_pgvalve_info.statid_incr[j], FS_OP_ADD, statistic_incr.num[j]);
+ }
+ }
+ for(int j=0; j<STAT_EXIST_NUM; j++)
+ {
+ statistic_exist_tt.num[j] += statistic_exist.num[j];
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, table->statid_table, g_pgvalve_info.statid_exist[j], FS_OP_SET, statistic_exist.num[j]);
+ }
+ }
+ }
+ MESA_handle_runtime_log(g_pgvalve_info.log_statistic, RLOG_LV_FATAL, "STAT_INFO_TOTAL_SWT",
+ "---------------------->RECV: %4llu, ERROR: %4llu, RVALID: %4llu, RINVALID: %4llu, DISP_SUCC: %4llu, DISP_FAIL: %4llu, DISP_LIMIT: %4llu; EXIST: %4llu, EACTIVE: %4llu, EINACTIVE: %4llu, PENDING: %4llu",
+ statistic_incr_tt.num[STAT_FIELD_RECV], statistic_incr_tt.num[STAT_FIELD_RERROR], statistic_incr_tt.num[STAT_FIELD_RVALID],
+ statistic_incr_tt.num[STAT_FIELD_RINVALID], statistic_incr_tt.num[STAT_FIELD_DISP_SUCC], statistic_incr_tt.num[STAT_FIELD_DISP_FAIL], statistic_incr_tt.num[STAT_FIELD_DISP_LIMIT],
+ statistic_exist_tt.num[STAT_FIELD_EXITS], statistic_exist_tt.num[STAT_FIELD_EACTIVE], statistic_exist_tt.num[STAT_FIELD_EINACTIVE], statistic_exist_tt.num[STAT_FIELD_PENDING]);
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ for(int j=0; j<STAT_INCR_NUM; j++)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, g_pgvalve_info.statid_table_sw, g_pgvalve_info.statid_incr[j], FS_OP_ADD, statistic_incr_tt.num[j]);
+ }
+ for(int j=0; j<STAT_EXIST_NUM; j++)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, g_pgvalve_info.statid_table_sw, g_pgvalve_info.statid_exist[j], FS_OP_SET, statistic_exist_tt.num[j]);
+ }
+ }
+
+ //ONE��ͳ��
+ memset(&statistic_incr_tt, 0, sizeof(statistic_incr_t));
+ memset(&statistic_exist_tt, 0, sizeof(statistic_exist_t));
+ for(iter=tables_one.begin(); iter!=tables_one.end(); iter++)
+ {
+ memset(&statistic_incr, 0, sizeof(statistic_incr_t));
+ memset(&statistic_exist, 0, sizeof(statistic_exist_t));
+
+ table = iter->second;
+ hash_key.service_id = table->service_id;
+ hash_key.table_id = table->table_id_key;
+ MESA_htable_search_cb(g_pgvalve_info.htable_stat_log, (uchar*)&hash_key, sizeof(stat_table_key_t), table_statistic_incr_cb, (void *)&statistic_incr, &cb_ret);
+ if(table->parent != NULL)
+ {
+ iterator_priv.table = table;
+ iterator_priv.stat_out = &statistic_exist;
+ MESA_htable_iterate_bytime(table->hash_handle, ITERATE_TYPE_OLDEST_FIRST, table_onesw_exist_iterate, (void *)&iterator_priv);
+ }
+ else
+ {
+ statistic_exist.num[STAT_FIELD_EXITS] = MESA_htable_get_elem_num(table->hash_handle);
+ }
+
+ MESA_handle_runtime_log(g_pgvalve_info.log_statistic, RLOG_LV_FATAL, "STAT_INFO_TABLE_ONE",
+ "%-20s-->RECV: %4llu, ERROR: %4llu, RVALID: %4llu, RINVALID: %4llu, DISP_SUCC: %4llu, DISP_FAIL: %4llu, DISP_LIMIT: %4llu; EXIST: %4llu, EACTIVE: %4llu, EINACTIVE: %4llu, PENDING: %4llu",
+ table->table_name, statistic_incr.num[STAT_FIELD_RECV], statistic_incr.num[STAT_FIELD_RERROR], statistic_incr.num[STAT_FIELD_RVALID],
+ statistic_incr.num[STAT_FIELD_RINVALID], statistic_incr.num[STAT_FIELD_DISP_SUCC], statistic_incr.num[STAT_FIELD_DISP_FAIL], statistic_incr.num[STAT_FIELD_DISP_LIMIT],
+ statistic_exist.num[STAT_FIELD_EXITS], statistic_exist.num[STAT_FIELD_EACTIVE], statistic_exist.num[STAT_FIELD_EINACTIVE], statistic_exist.num[STAT_FIELD_PENDING]);
+
+ for(int j=0; j<STAT_INCR_NUM; j++)
+ {
+ statistic_incr_tt.num[j] += statistic_incr.num[j];
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, table->statid_table, g_pgvalve_info.statid_incr[j], FS_OP_ADD, statistic_incr.num[j]);
+ }
+ }
+ for(int j=0; j<STAT_EXIST_NUM; j++)
+ {
+ statistic_exist_tt.num[j] += statistic_exist.num[j];
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, table->statid_table, g_pgvalve_info.statid_exist[j], FS_OP_SET, statistic_exist.num[j]);
+ }
+ }
+ }
+ MESA_handle_runtime_log(g_pgvalve_info.log_statistic, RLOG_LV_FATAL, "STAT_INFO_TOTAL_ONE",
+ "---------------------->RECV: %4llu, ERROR: %4llu, RVALID: %4llu, RINVALID: %4llu, DISP_SUCC: %4llu, DISP_FAIL: %4llu, DISP_LIMIT: %4llu; EXIST: %4llu, EACTIVE: %4llu, EINACTIVE: %4llu, PENDING: %4llu",
+ statistic_incr_tt.num[STAT_FIELD_RECV], statistic_incr_tt.num[STAT_FIELD_RERROR], statistic_incr_tt.num[STAT_FIELD_RVALID],
+ statistic_incr_tt.num[STAT_FIELD_RINVALID], statistic_incr_tt.num[STAT_FIELD_DISP_SUCC], statistic_incr_tt.num[STAT_FIELD_DISP_FAIL], statistic_incr_tt.num[STAT_FIELD_DISP_LIMIT],
+ statistic_exist_tt.num[STAT_FIELD_EXITS], statistic_exist_tt.num[STAT_FIELD_EACTIVE], statistic_exist_tt.num[STAT_FIELD_EINACTIVE], statistic_exist_tt.num[STAT_FIELD_PENDING]);
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ for(int j=0; j<STAT_INCR_NUM; j++)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, g_pgvalve_info.statid_table_one, g_pgvalve_info.statid_incr[j], FS_OP_ADD, statistic_incr_tt.num[j]);
+ }
+ for(int j=0; j<STAT_EXIST_NUM; j++)
+ {
+ FS_operate(g_pgvalve_info.fsstat_handle, g_pgvalve_info.statid_table_one, g_pgvalve_info.statid_exist[j], FS_OP_SET, statistic_exist_tt.num[j]);
+ }
+ }
+
+ //Serviceͳ�����
+ MESA_htable_iterate_bytime(g_pgvalve_info.htable_stat_serv, ITERATE_TYPE_OLDEST_FIRST, service_config_limit_iterator, NULL);
+ if(g_pgvalve_info.fsstatid_trig)
+ {
+ FS_passive_output(g_pgvalve_info.fsstat_handle);
+ }
+}
+
diff --git a/src/pg_valve_stat.h b/src/pg_valve_stat.h
new file mode 100644
index 0000000..0a3ccd6
--- /dev/null
+++ b/src/pg_valve_stat.h
@@ -0,0 +1,85 @@
+#ifndef __PANGU_VALVE_STAT_H__
+#define __PANGU_VALVE_STAT_H__
+
+#include <map>
+#include <iostream>
+#include <string>
+
+#include <MESA/field_stat2.h>
+#include <MESA/MESA_handle_logger.h>
+
+using namespace std;
+
+typedef enum __STAT_SERVICE_TYPE
+{
+ STAT_SERVICE_NONE=0,
+ STAT_SERVICE_ADD,
+ STAT_SERVICE_DEL,
+}STAT_SERVICE_TYPE_t;
+
+typedef struct __stat_service_priv
+{
+ u_int32_t log_num;
+ STAT_SERVICE_TYPE_t type;
+}stat_service_priv_t;
+
+typedef struct __stat_service_hnode
+{
+ u_int64_t cur_num;
+ u_int64_t max_num;
+}stat_service_hnode_t;
+
+typedef enum __STAT_FIELD_EXIST
+{
+ STAT_FIELD_EXITS=0,
+ STAT_FIELD_PENDING,
+ STAT_FIELD_EACTIVE,
+ STAT_FIELD_EINACTIVE,
+
+ STAT_EXIST_NUM,
+}STAT_FIELD_EXIST_t;
+
+typedef enum __STAT_FIELD_INCR
+{
+ STAT_FIELD_RECV=0,
+ STAT_FIELD_RERROR,
+ STAT_FIELD_RVALID,
+ STAT_FIELD_RINVALID,
+ STAT_FIELD_DISP_SUCC,
+ STAT_FIELD_DISP_FAIL,
+ STAT_FIELD_DISP_LIMIT,
+
+ STAT_INCR_NUM,
+}STAT_FIELD_INCR_t;
+
+typedef struct __statistic_exist
+{
+ u_int64_t num[STAT_EXIST_NUM];
+}statistic_exist_t;
+
+typedef struct __statistic_incr
+{
+ u_int64_t num[STAT_INCR_NUM];
+}statistic_incr_t;
+
+typedef struct __stat_table_key
+{
+ int32_t service_id;
+ int32_t table_id;
+}stat_table_key_t;
+
+typedef struct __stat_table_priv
+{
+ int64_t log_num;
+ STAT_FIELD_INCR_t type;
+}stat_table_priv_t;
+
+void pz_trans_statistic_count(int32_t service_id, int32_t table_id, int32_t log_num, STAT_FIELD_INCR_t type);
+
+int service_grule_setup_hnode(int32_t serv_type, u_int64_t max_num);
+void service_grule_statistic_count(int32_t serv_type, int32_t log_num, STAT_SERVICE_TYPE_t stat_type);
+bool service_grule_reach_limit(int32_t serv_type);
+void service_config_clear(void);
+
+#endif
+
diff --git a/src/pg_valve_tools.cpp b/src/pg_valve_tools.cpp
new file mode 100644
index 0000000..b7f11c8
--- /dev/null
+++ b/src/pg_valve_tools.cpp
@@ -0,0 +1,44 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int mkdir_according_path(const char * path)
+{
+ char buffer[256];
+ const char *ps=path, *pc;
+
+ if(*ps == '/')
+ ps += 1;
+
+ while((pc = strchr(ps, '/')) != NULL)
+ {
+ while(*(pc+1) == '/')
+ pc++;
+
+ memcpy(buffer, path, pc - path);
+ buffer[pc-path] = '\0';
+
+ if(access(buffer, F_OK))
+ {
+ if(mkdir(buffer, 0777))
+ {
+ return -1;
+ }
+ }
+
+ ps = pc + 1;
+ }
+ if(access(path, F_OK))
+ {
+ if(mkdir(path, 0777))
+ {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
diff --git a/src/pg_valve_tools.h b/src/pg_valve_tools.h
new file mode 100644
index 0000000..05a8852
--- /dev/null
+++ b/src/pg_valve_tools.h
@@ -0,0 +1,13 @@
+#ifndef __PANGU_VALVE_TOOLS_H__
+#define __PANGU_VALVE_TOOLS_H__
+
+#include <MESA/MESA_handle_logger.h>
+
+#define MESA_HANDLE_RUNTIME_LOGV2(handle, lv, mod, fmt, args...) \
+ MESA_handle_runtime_log((handle), (lv), (mod), "%s:%d, " fmt, __FILE__, __LINE__, ##args)
+
+int mkdir_according_path(const char * path);
+
+
+#endif
+
diff --git a/src/support/c3client_double_20181020.tgz b/src/support/c3client_double_20181020.tgz
new file mode 100644
index 0000000..68b09be
--- /dev/null
+++ b/src/support/c3client_double_20181020.tgz
Binary files differ
diff --git a/src/test_pg_valve.cpp b/src/test_pg_valve.cpp
new file mode 100644
index 0000000..1a65a5b
--- /dev/null
+++ b/src/test_pg_valve.cpp
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include "grule_for_view.h"
+
+int grule_app_status(grule_hdl_t hdl)
+{
+ return GRULE_APP_STATUS_CONNECTED;
+}
+
+grule_hdl_t grule_open()
+{
+ return malloc(1);
+}
+
+int grule_mask2flexible(const grule_t * src, grule_t * dst)
+{
+ return 0;
+}
+
+int grule_opt_set(grule_hdl_t hdl, int level, int type, const void * opt, size_t opt_size)
+{
+ return 0;
+}
+
+int grule_connect(grule_hdl_t hdl, const char * addr)
+{
+ return 0;
+}
+
+int grule_send(grule_hdl_t hdl, grule_t *rules, size_t rule_num, int flags)
+{
+ return rule_num;
+}
+
+int grule_cache_size(grule_hdl_t hdl)
+{
+ return 0;
+}
+
+const char * grule_error_str(int err_no)
+{
+ return "";
+}
+
+int grule_errno(grule_hdl_t hdl)
+{
+ return 0;
+}
+
+
+#define FILE_NAME "./firstconnect.txt"
+
+#define GRULE_SERVER_FIRST_CONNECT 1
+#define GRULE_SERVER_NONFIRST_CONNECT 0
+int grule_app_firstconnect_status(grule_hdl_t client)
+{
+ int first;
+
+ if(access(FILE_NAME, R_OK))
+ {
+ return GRULE_SERVER_NONFIRST_CONNECT;
+ }
+
+ FILE *fp = fopen(FILE_NAME, "r");
+ if(fp==NULL)
+ {
+ return GRULE_SERVER_NONFIRST_CONNECT;
+ }
+ if(fscanf(fp, "%u\n", &first) != 1)
+ {
+ fclose(fp);
+ return GRULE_SERVER_NONFIRST_CONNECT;
+ }
+ fclose(fp);
+
+ fp = fopen(FILE_NAME, "w");
+ if(fp==NULL)
+ {
+ return GRULE_SERVER_NONFIRST_CONNECT;
+ }
+ fwrite("0\n", 1, 2, fp);
+ fclose(fp);
+
+ return first?GRULE_SERVER_FIRST_CONNECT:GRULE_SERVER_NONFIRST_CONNECT;
+}
+
+char * parse_rule_str_full(grule_t * rule, char * buf, size_t *size)
+{
+ return buf;
+}
+
+
diff --git a/tools/create_tuple_combine_macro.c b/tools/create_tuple_combine_macro.c
new file mode 100644
index 0000000..df52cbf
--- /dev/null
+++ b/tools/create_tuple_combine_macro.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <fcntl.h>
+
+#include "grule_for_view.h"
+
+char macro[30][1024] = {
+"DIP",
+"DIP_PROTO",
+"DIP_DPORT_PROTO",
+"DIP_SPORT_PROTO",
+"DIP_SPORT_DPORT_PROTO",
+"SIP",
+"SIP_PROTO",
+"SIP_DPORT_PROTO",
+"SIP_SPORT_PROTO",
+"SIP_SPORT_DPORT_PROTO",
+"SIP_DIP",
+"SIP_DIP_PROTO",
+"SIP_DIP_DPORT_PROTO",
+"SIP_DIP_SPORT_PROTO",
+"SIP_DIP_SPORT_DPORT_PROTO",
+"DIP_MDIP",
+"DIP_MDIP_PROTO_MPROTO",
+"DIP_MDIP_DPORT_MDPORT_PROTO_MPROTO",
+"DIP_MDIP_SPORT_MSPORT_PROTO_MPROTO",
+"DIP_MDIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO",
+"SIP_MSIP",
+"SIP_MSIP_PROTO_MPROTO",
+"SIP_MSIP_DPORT_MDPORT_PROTO_MPROTO",
+"SIP_MSIP_SPORT_MSPORT_PROTO_MPROTO",
+"SIP_MSIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO",
+"SIP_MSIP_DIP_MDIP",
+"SIP_MSIP_DIP_MDIP_PROTO_MPROTO",
+"SIP_MSIP_DIP_MDIP_DPORT_MDPORT_PROTO_MPROTO",
+"SIP_MSIP_DIP_MDIP_SPORT_MSPORT_PROTO_MPROTO",
+"SIP_MSIP_DIP_MDIP_SPORT_MSPORT_DPORT_MDPORT_PROTO_MPROTO",
+};
+
+int main(int argc, char **argv)
+{
+ char *ptmp, *save_ptr;
+ grule_t grule;
+ char tmpstr[1024];
+
+ for(int i =0; i<30; i++)
+ {
+ save_ptr=NULL;
+ grule.rule_type.grule_type = 0;
+ sprintf(tmpstr, "%s", macro[i]);
+ for(ptmp = strtok_r(tmpstr, "_", &save_ptr); ptmp != NULL; ptmp = strtok_r(NULL, "_", &save_ptr))
+ {
+ if(!strcmp(ptmp, "SIP"))
+ {
+ grule.rule_type.sip_flag = 1;
+ }
+ else if(!strcmp(ptmp, "MSIP"))
+ {
+ grule.rule_type.sipmsk_flag= 1;
+ }
+ else if(!strcmp(ptmp, "DIP"))
+ {
+ grule.rule_type.dip_flag= 1;
+ }
+ else if(!strcmp(ptmp, "MDIP"))
+ {
+ grule.rule_type.dipmsk_flag= 1;
+ }
+ else if(!strcmp(ptmp, "SPORT"))
+ {
+ grule.rule_type.sport_flag= 1;
+ }
+ else if(!strcmp(ptmp, "MSPORT"))
+ {
+ grule.rule_type.spmsk_flag= 1;
+ }
+ else if(!strcmp(ptmp, "DPORT"))
+ {
+ grule.rule_type.dport_flag= 1;
+ }
+ else if(!strcmp(ptmp, "MDPORT"))
+ {
+ grule.rule_type.dpmsk_flag= 1;
+ }
+ else if(!strcmp(ptmp, "PROTO"))
+ {
+ grule.rule_type.proto_flag= 1;
+ }
+ else if(!strcmp(ptmp, "MPROTO"))
+ {
+ grule.rule_type.pmsk_flag= 1;
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+ printf("#define %s 0x%x\n", macro[i], grule.rule_type.grule_type);
+ }
+
+ printf("\n");
+ for(int i =0; i<30; i++)
+ {
+ printf("case %s:\n", macro[i]);
+ }
+
+ return 0;
+}
+