summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author崔一鸣 <[email protected]>2018-11-13 21:49:32 +0800
committer崔一鸣 <[email protected]>2018-11-13 21:49:32 +0800
commitde5be3b41f49183163a6576728b9578ad81d8d66 (patch)
tree6bda75e2699f2f699801ab178866239d282e6b5a
parent5beded2ed4be958e035061024271cbd4513abb1f (diff)
增加nat模块,ip管理模块
-rw-r--r--.vscode/ftp-kr.json2
-rw-r--r--.vscode/ftp-kr.sync.cache.json174
-rw-r--r--access/CMakeLists.txt29
-rw-r--r--access/include/ip_mgr.h13
-rw-r--r--access/include/nat.h8
-rw-r--r--access/include/tun.h20
-rw-r--r--access/include/vpn_monitor.h10
-rw-r--r--access/src/ip_mgr.cpp374
-rw-r--r--access/src/main.cpp156
-rw-r--r--access/src/nat.cpp384
-rw-r--r--access/src/vpn_monitor.cpp253
-rw-r--r--access/test/test_MESA_htable.cpp47
-rw-r--r--access/test/test_maat_redis.cpp10
-rw-r--r--access/test/test_tun.cpp (renamed from access/src/tun.cpp)211
-rw-r--r--common/CMakeLists.txt2
-rw-r--r--common/include/mgw_socket.h0
-rw-r--r--common/include/mgw_tun.h11
-rw-r--r--common/include/mgw_utils.h38
-rw-r--r--common/src/mgw_socket.cpp0
-rw-r--r--common/src/mgw_tun.cpp108
-rw-r--r--common/src/mgw_utils.cpp62
-rw-r--r--conf/mgw.conf23
-rw-r--r--conf/table_info.conf18
23 files changed, 1654 insertions, 299 deletions
diff --git a/.vscode/ftp-kr.json b/.vscode/ftp-kr.json
index e1bd0e2..15d90ae 100644
--- a/.vscode/ftp-kr.json
+++ b/.vscode/ftp-kr.json
@@ -1,5 +1,5 @@
{
- "host": "192.168.10.180",
+ "host": "192.168.11.137",
"username": "root",
"password": "111111",
"remotePath": "/root/IPReuse/mgw/",
diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json
new file mode 100644
index 0000000..ac0ee69
--- /dev/null
+++ b/.vscode/ftp-kr.sync.cache.json
@@ -0,0 +1,174 @@
+{
+ "sftp://192.168.11.137:22@root": {
+ "root": {
+ "IPReuse": {
+ "mgw": {
+ "common": {
+ "include": {
+ "mgw_utils.h": {
+ "type": "-",
+ "size": 1669,
+ "lmtime": 1541749644647,
+ "modified": false
+ },
+ "tun.h": {
+ "type": "-",
+ "size": 294,
+ "lmtime": 1541750944509,
+ "modified": false
+ }
+ },
+ "CMakeLists.txt": {
+ "type": "-",
+ "size": 174,
+ "lmtime": 1541749907789,
+ "modified": false
+ },
+ "src": {
+ "mgw_utils.cpp": {
+ "type": "-",
+ "size": 2357,
+ "lmtime": 1541748400171,
+ "modified": false
+ },
+ "tun.cpp": {
+ "type": "-",
+ "size": 2742,
+ "lmtime": 1541750772819,
+ "modified": false
+ }
+ }
+ },
+ "CMakeLists.txt": {
+ "type": "-",
+ "size": 353,
+ "lmtime": 1540963722549,
+ "modified": false
+ },
+ "README.md": {
+ "type": "-",
+ "size": 26,
+ "lmtime": 1540888536383,
+ "modified": false
+ },
+ "access": {
+ "CMakeLists.txt": {
+ "type": "-",
+ "size": 1093,
+ "lmtime": 1541746572765,
+ "modified": false
+ },
+ "include": {
+ "vpn_monitor.h": {
+ "type": "-",
+ "size": 316,
+ "lmtime": 1541745105496,
+ "modified": false
+ },
+ "nat.cpp": {
+ "type": "-",
+ "size": 0,
+ "lmtime": 1541751728308,
+ "modified": false
+ },
+ "nat.h": {
+ "type": "-",
+ "size": 0,
+ "lmtime": 1541751736748,
+ "modified": false
+ }
+ },
+ "src": {
+ "main.cpp": {
+ "type": "-",
+ "size": 6385,
+ "lmtime": 1541751403568,
+ "modified": false
+ },
+ "tun.cpp": {
+ "type": "-",
+ "size": 2734,
+ "lmtime": 1541164401820,
+ "modified": false
+ },
+ "vpn_monitor.cpp": {
+ "type": "-",
+ "size": 8266,
+ "lmtime": 1541748000824,
+ "modified": false
+ },
+ "nat.cpp": {
+ "type": "-",
+ "size": 3068,
+ "lmtime": 1541771190090,
+ "modified": false
+ },
+ "ip_translator.cpp": {
+ "type": "-",
+ "size": 0,
+ "lmtime": 1541664138444,
+ "modified": false
+ },
+ "ip_manager.cpp": {
+ "type": "-",
+ "size": 0,
+ "lmtime": 1541751456565,
+ "modified": false
+ },
+ "ip_pool_mgr.cpp": {
+ "type": "-",
+ "size": 0,
+ "lmtime": 1541751709640,
+ "modified": false
+ }
+ },
+ "test": {
+ "test_maat_redis.cpp": {
+ "type": "-",
+ "size": 6241,
+ "lmtime": 1541320257970,
+ "modified": false
+ },
+ "test_tun.cpp": {
+ "type": "-",
+ "size": 3123,
+ "lmtime": 1541751177033,
+ "modified": false
+ }
+ }
+ },
+ "vendor": {
+ "CMakeLists.txt": {
+ "type": "-",
+ "size": 1741,
+ "lmtime": 1540969696627,
+ "modified": false
+ },
+ "maat-v2.3.3.tar.gz": {
+ "type": "-",
+ "size": 1920396,
+ "lmtime": 1540888536391,
+ "modified": false
+ }
+ },
+ "build": {},
+ "conf": {
+ "table_info.conf": {
+ "type": "-",
+ "size": 604,
+ "lmtime": 1541321983862,
+ "modified": false
+ },
+ "mgw.conf": {
+ "type": "-",
+ "size": 447,
+ "lmtime": 1541321983862,
+ "modified": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "$version": 1
+} \ No newline at end of file
diff --git a/access/CMakeLists.txt b/access/CMakeLists.txt
index c68729a..6fa5bf6 100644
--- a/access/CMakeLists.txt
+++ b/access/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_executable(mgw src/main.cpp src/tun.cpp)
+add_executable(mgw src/main.cpp src/vpn_monitor.cpp src/nat.cpp src/ip_mgr.cpp)
target_include_directories(mgw PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
@@ -15,7 +15,7 @@ target_link_libraries(mgw pthread dl
# target_link_libraries(tfe -Wl,--whole-archive pangu-http -Wl,--no-whole-archive)
-add_executable(test_maat_redis test/test_maat_redis.cpp)
+#[[add_executable(test_maat_redis test/test_maat_redis.cpp)
target_include_directories(test_maat_redis PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
@@ -26,4 +26,27 @@ target_link_libraries(test_maat_redis pthread dl
MESA_htable
wiredcfg
MESA_field_stat
- maatframe) \ No newline at end of file
+ maatframe)]]
+
+
+add_executable(test_tun test/test_tun.cpp)
+
+target_include_directories(test_tun PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
+
+target_link_libraries(test_tun common)
+target_link_libraries(test_tun pthread dl
+ MESA_handle_logger
+ MESA_prof_load
+ MESA_htable
+ )
+
+add_executable(test_htable test/test_MESA_htable.cpp)
+
+target_include_directories(test_htable PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
+
+target_link_libraries(test_htable common)
+target_link_libraries(test_htable pthread dl
+ MESA_handle_logger
+ MESA_prof_load
+ MESA_htable
+ ) \ No newline at end of file
diff --git a/access/include/ip_mgr.h b/access/include/ip_mgr.h
new file mode 100644
index 0000000..6d4f73d
--- /dev/null
+++ b/access/include/ip_mgr.h
@@ -0,0 +1,13 @@
+struct cand_ip
+{
+ uint32_t ip;
+ int reference;
+};
+
+struct ip_mgr_handle;
+struct ip_mgr_handle *ip_mgr_init(void *logger, Maat_feather_t feather, struct htable_opts* opts);
+void ip_mgr_destroy(struct ip_mgr_handle *handle);
+struct cand_ip* ip_mgr_candidata_ip_get(struct ip_mgr_handle *handle, const char *user_name);
+bool ip_mgr_candidate_ip_verify(struct ip_mgr_handle *handle, uint32_t ip);
+
+
diff --git a/access/include/nat.h b/access/include/nat.h
new file mode 100644
index 0000000..a18c119
--- /dev/null
+++ b/access/include/nat.h
@@ -0,0 +1,8 @@
+#define NAT_COVERT_SUCCESS -1
+#define NAT_COVERT_FAILURE 0
+
+struct nat_handle;
+struct nat_handle * nat_init(MESA_htable_handle htable, void *logger, struct htable_opts* opts);
+void nat_destroy(struct nat_handle *handle);
+int nat_src_convert(struct nat_handle *handle, struct ip_mgr_handle *_ip_mgr_handle, char *buff, int len);
+int nat_dest_convert(struct nat_handle *handle, char *buff, int len); \ No newline at end of file
diff --git a/access/include/tun.h b/access/include/tun.h
deleted file mode 100644
index 4673a0c..0000000
--- a/access/include/tun.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef TUN_H_INCLUDED
-#define TUN_H_INCLUDED
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include<assert.h>
-#include <sys/ioctl.h>
-#include<linux/if_ether.h>
-#include<stddef.h>
-#include<net/if.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#include <unistd.h>
-
-
-int tun_alloc(char *dev);
-int write_to_tun(int tun_fd, char *send_ip_pkts, int send_ip_len);
-int read_from_tun(int tun_fd, char *recv_ip_pkts,size_t ip_pkt_len);
-#endif // TUN_H_INCLUDED
diff --git a/access/include/vpn_monitor.h b/access/include/vpn_monitor.h
new file mode 100644
index 0000000..990195f
--- /dev/null
+++ b/access/include/vpn_monitor.h
@@ -0,0 +1,10 @@
+#pragma once
+
+struct vpn_monitor_args
+{
+ MESA_htable_handle ip2user_htable;
+ void *logger;
+ const char *profile;
+};
+
+void * thread_vpn_monitor(void* arg); \ No newline at end of file
diff --git a/access/src/ip_mgr.cpp b/access/src/ip_mgr.cpp
new file mode 100644
index 0000000..0322463
--- /dev/null
+++ b/access/src/ip_mgr.cpp
@@ -0,0 +1,374 @@
+
+
+#include "mgw_utils.h"
+#include "ip_mgr.h"
+#define GROUP_IP_MAX 4096
+
+/*
+{
+ "plugin_table":[
+ {
+ "table_name":"IR_CANDINATE_IP",
+ "table_content":[
+ "1\t101\t4\t202.104.1.123\t0\t192.168.10.180\t1\t0\t0\t4789\t50000\t192.168.14.1\t10.2.2.2\t24:6e:96:c9:77:d0\t00:1e:73:6c:fa:44\te8:61:1f:13:70:7a\t18:31:bf:e4:a5:a0\t1"
+ ]
+ },
+ {
+ "table_name":"IR_POLICY",
+ "table_content":[
+ "1\t101\t0\tuser\t1"
+ ]
+ }
+ ]
+}
+*/
+
+struct ip_mgr_handle
+{
+ void *logger;
+ Maat_feather_t feather;
+ MESA_htable_handle user_policy_htable; //expire_time: 0
+ MESA_htable_handle cand_ip_htable; //expire_time: 0
+ MESA_htable_handle ip_verify_htable; //expire_time: 0
+};
+
+struct user_policy_htable_value
+{
+ char user_name[MGW_SYMBOL_MAX];
+ int group_id;
+};
+
+struct ip_verify_htable_value
+{
+ uint32_t ip;
+ bool is_valid;
+};
+struct cand_ip_htable_value
+{
+ struct cand_ip *ip_group[GROUP_IP_MAX];
+ unsigned int num;
+};
+
+
+static long ip_verify_htable_query_cb(void *data, const uchar *key, uint size, void *user_args)
+{
+ bool *is_valid = (bool *)user_args;
+ if(data != NULL)
+ {
+ struct ip_verify_htable_value *_data = (struct ip_verify_htable_value*)data;
+ *is_valid = _data->is_valid;
+ return HTABLE_KEY_EXISTED;
+ }
+ return HTABLE_KEY_NOT_EXISTED;
+}
+
+bool ip_mgr_candidate_ip_verify(struct ip_mgr_handle *handle, uint32_t ip)
+{
+ long ip_verify_cb_rtn = 0;
+ bool is_valid;
+ MESA_htable_search_cb(handle->ip_verify_htable, (const unsigned char *)(&ip), sizeof(ip), ip_verify_htable_query_cb, &is_valid, &ip_verify_cb_rtn);
+ if(ip_verify_cb_rtn == HTABLE_KEY_EXISTED)
+ {
+ if(is_valid == true)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+static long user_policy_htable_query_cb(void *data, const uchar *key, uint size, void *user_args)
+{
+ struct user_policy_htable_value *value = (struct user_policy_htable_value *)data;
+ int *group_id = (int *)user_args;
+ if(data != NULL)
+ {
+ *group_id = value->group_id;
+ return HTABLE_KEY_EXISTED;
+ }
+ return HTABLE_KEY_NOT_EXISTED;
+}
+
+
+struct cand_ip* ip_mgr_candidata_ip_get(struct ip_mgr_handle *handle, const char *user_name)
+{
+ void *logger = handle->logger;
+ long user_policy_cb_rtn = 0;
+ int group_id;
+ int key_size = strnlen(user_name, MGW_SYMBOL_MAX);
+ MESA_htable_search_cb(handle->user_policy_htable, (const unsigned char *)user_name, key_size, user_policy_htable_query_cb, &group_id, &user_policy_cb_rtn);
+ if(user_policy_cb_rtn == HTABLE_KEY_EXISTED)
+ {
+ MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, key is %s, group id is %d", "user_policy", user_name, group_id);
+ struct cand_ip_htable_value *ip_group = NULL;
+ ip_group = (struct cand_ip_htable_value *)MESA_htable_search(handle->cand_ip_htable, (const unsigned char *)(&group_id), sizeof(group_id));
+ if(ip_group != NULL)
+ {
+ unsigned int num = ip_group->num;
+ if(num <= 0)
+ {
+ MGW_LOG_ERROR(logger, "The cand_ip is empty, group_id is %d", group_id);
+ return NULL;
+ }
+ unsigned int index = mgw_utils_get_random(num);
+ return ip_group->ip_group[index];
+ }
+ else
+ {
+ MGW_LOG_ERROR(logger, "MESA_htable: key not existed. table is %s, key is %d", "cand_ip_htable", group_id);
+ return NULL;
+ }
+ }
+ else
+ {
+ MGW_LOG_ERROR(logger, "MESA_htable: key not existed. table is %s, key is %s", "user_policy_htable", user_name);
+ return NULL;
+ }
+}
+
+static void user_info_htable_data_free_cb(void *data)
+{
+ FREE(&data);
+}
+
+static void cand_ip_htable_data_free_cb(void *data)
+{
+ FREE(&data);
+}
+
+static void ip_verify_htable_data_free_cb(void *data)
+{
+ FREE(&data);
+}
+
+static int delete_ip_from_group(uint32_t ip, struct cand_ip_htable_value *ip_group)
+{
+ int num = ip_group->num;
+ int pos = -1;
+ for(int i = 0; i < num; i++)
+ {
+ if(ip_group->ip_group[i]->ip == ip)
+ {
+ pos = i;
+ break;
+ }
+ }
+ if(pos == -1)
+ {
+ return -1;
+ }
+ for(int i = pos; i < num - 1; i++)
+ {
+ ip_group->ip_group[i] = ip_group->ip_group[i + 1];
+ }
+ ip_group->num --;
+ return 0;
+}
+
+
+static void Maat_user_policy_start_cb(int update_type,void* args)
+{
+ struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args;
+ void *logger = handle->logger;
+ MGW_LOG_INFO(logger, "Maat_redis: start callback, table is USER_POLICY_TABLE");
+ return;
+}
+
+static void Maat_user_policy_update_cb(int table_id, const char* table_line, void* args)
+{
+ struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args;
+ void *logger = handle->logger;
+ MGW_LOG_INFO(logger, "Maat_redis: update callback, table is USER_POLICY_TABLE");
+ int config_id, group_id, user_type, is_valid;
+ char user_name[MGW_SYMBOL_MAX];
+ sscanf(table_line, "%d %d %d %s %d", &config_id, &group_id, &user_type, user_name, &is_valid);
+ struct user_policy_htable_value *value = ALLOC(struct user_policy_htable_value, 1);
+ strncpy(value->user_name, user_name, MGW_SYMBOL_MAX);
+ value->group_id = group_id;
+ int key_size = strnlen(user_name, MGW_SYMBOL_MAX);
+ if(is_valid == 1)
+ {
+ //add user_policy_htable
+ int rtn = MESA_htable_add(handle->user_policy_htable, (const unsigned char *)user_name, key_size, value);
+ if(rtn < 0)
+ {
+ MGW_LOG_ERROR(handle->logger, "MESA_htable: failed at add, table is %s, user_name is %s, group_id is %d", "user_policy_htable", user_name, group_id);
+ }
+ }
+ else
+ {
+ //del user_policy_htable
+ int rtn = MESA_htable_del(handle->user_policy_htable, (const unsigned char *)user_name, key_size, NULL);
+ if(rtn < 0)
+ {
+ MGW_LOG_ERROR(handle->logger, "MESA_htable: failed at del, table is %s, user_name is %s, group_id is %d", "user_policy_htable", user_name, group_id);
+ }
+ }
+ return;
+}
+
+
+static void Maat_user_policy_finish_cb(void* args)
+{
+ struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args;
+ void *logger = handle->logger;
+ Maat_feather_t feather = handle->feather;
+ MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is USER_POLICY_TABLE");
+ /*
+ long long version=0;
+ int ret=0, is_last_updating_table = 0;
+ ret = Maat_read_state(feather, MAAT_STATE_VERSION, &version, sizeof(version));
+ printf("version is %d\n", version);
+ assert(ret==0);
+ ret=Maat_read_state(feather,MAAT_STATE_LAST_UPDATING_TABLE, &is_last_updating_table, sizeof(is_last_updating_table));
+ printf("is_last_updating_table is %d\n", is_last_updating_table);
+ assert(ret==0);
+ */
+ return;
+}
+
+static void Maat_cand_ip_start_cb(int update_type,void* args)
+{
+ struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args;
+ void *logger = handle->logger;
+ MGW_LOG_INFO(logger, "Maat_redis: start callback, table is CAND_IP_TABLE");
+ return;
+}
+
+static void Maat_cand_ip_update_cb(int table_id, const char* table_line, void* args)
+{
+ struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args;
+ void *logger = handle->logger;
+ MGW_LOG_INFO(logger, "Maat_redis: update callback, table is CAND_IP_TABLE");
+ int config_id, group_id, addr_type, location, link_id, encap_type, direction, is_valid;
+ char ip_addr[MGW_SYMBOL_MAX];
+ char mrl_ip[MGW_SYMBOL_MAX];
+ char outer_sport[MGW_SYMBOL_MAX];
+ char outer_dport[MGW_SYMBOL_MAX];
+ char outer_sip[MGW_SYMBOL_MAX];
+ char outer_dip[MGW_SYMBOL_MAX];
+ char outer_smac[MGW_SYMBOL_MAX];
+ char outer_dmac[MGW_SYMBOL_MAX];
+ char inner_smac[MGW_SYMBOL_MAX];
+ char inner_dmac[MGW_SYMBOL_MAX];
+ sscanf(table_line, "%d %d %d %s %d %s %d %d %d %s %s %s %s %s %s %s %s %d", &config_id, &group_id, &addr_type, ip_addr, &location, mrl_ip, &link_id, &encap_type, &direction, outer_sport, outer_dport,
+ outer_sip, outer_dip, outer_smac, outer_dmac, inner_smac, inner_dmac, &is_valid);
+ uint32_t ip = inet_addr(ip_addr);
+ if(is_valid == 1)
+ {
+ //add cand_ip_htable
+ struct cand_ip_htable_value *ip_group = NULL;
+ ip_group = (struct cand_ip_htable_value *)MESA_htable_search(handle->cand_ip_htable, (const unsigned char *)(&group_id), sizeof(group_id));
+ if(ip_group == NULL)
+ {
+ ip_group = ALLOC(struct cand_ip_htable_value, 1);
+ ip_group->num = 0;
+ int rtn = MESA_htable_add(handle->cand_ip_htable, (const unsigned char *)&group_id, sizeof(group_id), (void *)ip_group);
+ if(rtn < 0)
+ {
+ MGW_LOG_ERROR(logger, "MESA_htable: failed at add, table is %s, group_id is %d", "cand_ip_htable", group_id);
+ return;
+ }
+ }
+ struct cand_ip *_cand_ip = ALLOC(struct cand_ip, 1);
+ _cand_ip->ip = ip;
+ _cand_ip->reference = 0;
+ int num = ip_group->num;
+ ip_group->ip_group[num] = _cand_ip;
+ ip_group->num ++;
+ }
+ else
+ {
+ struct cand_ip_htable_value *ip_group = NULL;
+ ip_group = (struct cand_ip_htable_value *)MESA_htable_search(handle->cand_ip_htable, (const unsigned char *)(&group_id), sizeof(group_id));
+ if(ip_group == NULL)
+ {
+ MGW_LOG_ERROR(logger, "Failed at del ip from ip_group, group_id %d not existed in cand_ip_htable", group_id);
+ return;
+ }
+ int rtn = delete_ip_from_group(ip, ip_group);
+ if(rtn == -1)
+ {
+ MGW_LOG_ERROR(logger, "Failed at del ip from ip_group, ip %s not in group %d", ip_addr, group_id);
+ return;
+ }
+ }
+ return;
+}
+
+
+static void Maat_cand_ip_finish_cb(void* args)
+{
+ struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args;
+ void *logger = handle->logger;
+ Maat_feather_t feather = handle->feather;
+ MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is CAND_IP_TABLE");
+ /*
+ long long version=0;
+ int ret=0, is_last_updating_table = 0;
+ ret = Maat_read_state(feather, MAAT_STATE_VERSION, &version, sizeof(version));
+ printf("version is %d\n", version);
+ assert(ret==0);
+ ret=Maat_read_state(feather,MAAT_STATE_LAST_UPDATING_TABLE, &is_last_updating_table, sizeof(is_last_updating_table));
+ printf("is_last_updating_table is %d\n", is_last_updating_table);
+ assert(ret==0);
+ */
+ return;
+}
+
+static int Maat_plugin_register(Maat_feather_t feather, const char* table_name, Maat_start_callback_t *start,
+ Maat_update_callback_t *update, Maat_finish_callback_t *finish, struct ip_mgr_handle *handle)
+{
+ int table_id = 0, ret = 0;
+ void *logger = handle->logger;
+ table_id = Maat_table_register(feather, table_name);
+ if(table_id == -1)
+ {
+ MGW_LOG_ERROR(logger, "Maat_redis: database table %s register failed", table_name);
+ return -1;
+ }
+ else
+ {
+ ret = Maat_table_callback_register(feather, table_id, start, update, finish, (void *)handle);
+ if(ret < 0)
+ {
+ MGW_LOG_ERROR(logger, "Maat_redis: callback register table %s error", table_name);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+struct ip_mgr_handle *ip_mgr_init(void *logger, Maat_feather_t feather, struct htable_opts* opts)
+{
+ struct ip_mgr_handle *handle = ALLOC(struct ip_mgr_handle, 1);
+ handle->logger = logger;
+ handle->feather = feather;
+ handle->user_policy_htable = mgw_utils_create_htable("user_info_htable", opts, (void *)user_info_htable_data_free_cb, NULL);
+ handle->cand_ip_htable = mgw_utils_create_htable("cand_ip_htable", opts, (void *)cand_ip_htable_data_free_cb, NULL);
+ handle->ip_verify_htable = mgw_utils_create_htable("ip_verify_htable", opts, (void *)ip_verify_htable_data_free_cb, NULL);
+ Maat_plugin_register(feather, "USER_POLICY_TABLE", Maat_user_policy_start_cb, Maat_user_policy_update_cb, Maat_user_policy_finish_cb, handle);
+ Maat_plugin_register(feather, "CAND_IP_TABLE", Maat_cand_ip_start_cb, Maat_cand_ip_update_cb, Maat_cand_ip_finish_cb, handle);
+ return handle;
+}
+
+void ip_mgr_destroy(struct ip_mgr_handle *handle)
+{
+ MESA_htable_destroy(handle->user_policy_htable, user_info_htable_data_free_cb);
+ MESA_htable_destroy(handle->cand_ip_htable, cand_ip_htable_data_free_cb);
+ MESA_htable_destroy(handle->ip_verify_htable, ip_verify_htable_data_free_cb);
+ FREE(&handle);
+}
+
+
+
+
diff --git a/access/src/main.cpp b/access/src/main.cpp
index b4f4aab..7a92bc3 100644
--- a/access/src/main.cpp
+++ b/access/src/main.cpp
@@ -1,50 +1,31 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <pthread.h>
-#include "MESA/MESA_prof_load.h"
-#include "MESA/MESA_handle_logger.h"
#include "mgw_utils.h"
-#include "Maat_rule.h"
-#include "Maat_command.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-struct htable_opt
-{
- int mho_screen_print_ctrl;
- int mho_thread_safe;
- int mho_mutex_num;
- int mho_hash_slot_size;
- int mho_expire_time;
-}
+#include "vpn_monitor.h"
+#include "mgw_tun.h"
+#include "nat.h"
+#include "ip_mgr.h"
-struct mgw_ctx
+struct mgw_handle
{
void* logger;
const char *profile;
Maat_feather_t Maat_feather;
- struct htable_opt *_htable_opt;
- struct vpn_monitor_ctx *_vpn_monitor_ctx;
+ struct htable_opts *htable_opts_s;
+ struct mgw_tun_handle *mgw_tun_handle_s;
+ struct nat_handle *nat_handle_s;
+ struct ip_mgr_handle *ip_mgr_handle_s;
};
-struct mgw_ctx g_mgw_ctx;
-
-static void wrapped_Maat_set_feather_opt(Maat_feather_t feather, enum MAAT_INIT_OPT type, const void* value, int size)
+static void wrapped_Maat_set_feather_opt(void *logger, Maat_feather_t feather, enum MAAT_INIT_OPT type, const void* value, int size)
{
int rtn = Maat_set_feather_opt(feather, type, value, size);
if(unlikely(rtn < 0))
{
- MGW_LOG_ERROR(g_mgw_ctx.logger, "Failed at Maat_set_feather_opt, type is %d", type);
+ MGW_LOG_ERROR(logger, "Failed at Maat_set_feather_opt, type is %d", type);
exit(EXIT_FAILURE);
}
}
-static void Maat_init()
+static Maat_feather_t Maat_init(const char *profile, void *logger)
{
// load conf
const char *section = "Maat";
@@ -53,25 +34,26 @@ static void Maat_init()
char Maat_redis_ip[MGW_SYMBOL_MAX];
int Maat_redis_port;
char stat_file_path[MGW_PATH_MAX];
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "table_info_path", table_info_path, sizeof(table_info_path), "./conf/table_info.conf");
- MESA_load_profile_int_def(g_mgw_ctx.profile, section, "max_thread_num", &max_thread_num, 1);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "Maat_redis_ip", Maat_redis_ip, sizeof(Maat_redis_ip), "127.0.0.1");
- MESA_load_profile_int_def(g_mgw_ctx.profile, section, "Maat_redis_port", &Maat_redis_port, 6379);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "stat_file_path", stat_file_path, sizeof(stat_file_path), "./log/Maat_stat.log");
-
+ MESA_load_profile_string_def(profile, section, "table_info_path", table_info_path, sizeof(table_info_path), "./conf/table_info.conf");
+ MESA_load_profile_int_def(profile, section, "max_thread_num", &max_thread_num, 1);
+ MESA_load_profile_string_def(profile, section, "Maat_redis_ip", Maat_redis_ip, sizeof(Maat_redis_ip), "127.0.0.1");
+ MESA_load_profile_int_def(profile, section, "Maat_redis_port", &Maat_redis_port, 6379);
+ MESA_load_profile_string_def(profile, section, "stat_file_path", stat_file_path, sizeof(stat_file_path), "./log/Maat_stat.log");
+ MGW_LOG_INFO(logger, "MESA_prof_load, [%s]:\n table_info_path: %s\n max_thread_num: %d\n Maat_redis_ip: %s\n Maat_redis_port: %d\n stat_file_path: %s", "Maat", table_info_path, max_thread_num, Maat_redis_ip, Maat_redis_port, stat_file_path);
// init Maat
Maat_feather_t feather = NULL;
- feather = Maat_feather(max_thread_num, table_info_path, g_mgw_ctx.logger);
+ feather = Maat_feather(max_thread_num, table_info_path, logger);
if(feather == NULL)
{
+ MGW_LOG_ERROR(logger, "Failed at Maat_feather");
exit(EXIT_FAILURE);
}
- wrapped_Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, "mgw", strlen("mgw")+1);
- wrapped_Maat_set_feather_opt(feather, MAAT_OPT_REDIS_IP, Maat_redis_ip, strlen(Maat_redis_ip)+1);
- wrapped_Maat_set_feather_opt(feather, MAAT_OPT_REDIS_PORT, &Maat_redis_port, sizeof(Maat_redis_port));
- wrapped_Maat_set_feather_opt(feather, MAAT_OPT_STAT_FILE_PATH, stat_file_path, strlen(stat_file_path)+1);
- wrapped_Maat_set_feather_opt(feather, MAAT_OPT_STAT_ON, NULL, 0);
- wrapped_Maat_set_feather_opt(feather, MAAT_OPT_PERF_ON, NULL, 0);
+ wrapped_Maat_set_feather_opt(logger, feather, MAAT_OPT_INSTANCE_NAME, "mgw", strlen("mgw")+1);
+ wrapped_Maat_set_feather_opt(logger, feather, MAAT_OPT_REDIS_IP, Maat_redis_ip, strlen(Maat_redis_ip)+1);
+ wrapped_Maat_set_feather_opt(logger, feather, MAAT_OPT_REDIS_PORT, &Maat_redis_port, sizeof(Maat_redis_port));
+ wrapped_Maat_set_feather_opt(logger, feather, MAAT_OPT_STAT_FILE_PATH, stat_file_path, strlen(stat_file_path)+1);
+ wrapped_Maat_set_feather_opt(logger, feather, MAAT_OPT_STAT_ON, NULL, 0);
+ wrapped_Maat_set_feather_opt(logger, feather, MAAT_OPT_PERF_ON, NULL, 0);
//wrapped_Maat_set_feather_opt(feather, MAAT_OPT_SCANDIR_INTERVAL_MS,&scan_interval_ms, sizeof(scan_interval_ms));
//wrapped_Maat_set_feather_opt(feather, MAAT_OPT_EFFECT_INVERVAL_MS, &effective_interval_ms, sizeof(effective_interval_ms));
//wrapped_Maat_set_feather_opt(feather, MAAT_OPT_SCAN_DETAIL, &scan_detail, sizeof(scan_detail));
@@ -79,69 +61,95 @@ static void Maat_init()
int rtn = Maat_initiate_feather(feather);
if(unlikely(rtn < 0))
{
- MGW_LOG_ERROR(g_mgw_ctx.logger, "Failed at Maat_initiate_feather");
+ MGW_LOG_ERROR(logger, "Failed at Maat_initiate_feather");
exit(EXIT_FAILURE);
}
- g_mgw_ctx.Maat_feather = feather;
+ return feather;
}
-static void htable_opt_init()
+static struct htable_opts * htable_opt_init(const char* profile, void *logger)
{
- struct htable_opt* _htable_opt = ALLOC(struct htable_opt, 1);
+ struct htable_opts* _htable_opts = ALLOC(struct htable_opts, 1);
const char *section = "htable_opt";
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "mho_screen_print_ctrl", _htable_opt->mho_screen_print_ctrl, sizeof(int), 0);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "mho_thread_safe", _htable_opt->_htable_opt.mho_thread_safe, sizeof(int), 1);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "mho_mutex_num", _htable_opt->_htable_opt.mho_mutex_num, sizeof(int), 16);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "mho_hash_slot_size", _htable_opt->_htable_opt.mho_hash_slot_size, sizeof(int), 16);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "mho_expire_time", _htable_opt->_htable_opt.mho_expire_time, sizeof(int), -1);
- g_mgw_ctx._htable_opt = _htable_opt;
+ MESA_load_profile_int_def(profile, section, "mho_screen_print_ctrl", &(_htable_opts->mho_screen_print_ctrl), 0);
+ MESA_load_profile_int_def(profile, section, "mho_thread_safe", &(_htable_opts->mho_thread_safe), 1);
+ MESA_load_profile_int_def(profile, section, "mho_mutex_num", &(_htable_opts->mho_mutex_num), 16);
+ MESA_load_profile_int_def(profile, section, "mho_hash_slot_size", &(_htable_opts->mho_hash_slot_size), 16);
+ MESA_load_profile_int_def(profile, section, "mho_expire_time", &(_htable_opts->mho_expire_time), 0);
+ MGW_LOG_INFO(logger, "MESA_prof_load, [%s]:\n mho_screen_print_ctrl: %d\n mho_thread_safe: %d\n mho_mutex_num: %d\n mho_hash_slot_size: %d\n mho_expire_time: %d",
+ "htable_opt", _htable_opts->mho_screen_print_ctrl, _htable_opts->mho_thread_safe, _htable_opts->mho_mutex_num, _htable_opts->mho_hash_slot_size, _htable_opts->mho_expire_time);
+ return _htable_opts;
}
-static void mgw_init()
+void ip2user_htable_free_data_cb(void *data)
{
- g_mgw_ctx.profile = "./conf/mgw.conf";
+ FREE(&data);
+}
+
+static struct mgw_handle * mgw_init()
+{
+ const char *profile = "./conf/mgw.conf";
const char *section = "global";
char log_path[MGW_PATH_MAX];
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "log_path", log_path, sizeof(log_path), "./log/mgw.log");
+ MESA_load_profile_string_def(profile, section, "log_path", log_path, sizeof(log_path), "./log/mgw.log");
void *logger = MESA_create_runtime_log_handle(log_path, RLOG_LV_DEBUG);
if (unlikely(logger == NULL))
{
- MGW_LOG_ERROR(g_mgw_ctx.logger, "Failed at creating logger: %s", log_path);
+ MGW_LOG_ERROR(logger, "Failed at creating logger: %s", log_path);
exit(EXIT_FAILURE);
}
- g_mgw_ctx.logger = logger;
- htable_opt_init();
- Maat_init();
+ MGW_LOG_INFO(logger, "MESA_prof_load, [%s]:\n log_path: %s", "global", log_path);
+ struct mgw_handle *_mgw_handle = ALLOC(struct mgw_handle, 1);
+ _mgw_handle->logger = logger;
+ struct htable_opts * _htable_opts = htable_opt_init(profile, logger);
+ _mgw_handle->htable_opts_s = _htable_opts;
+ Maat_feather_t Maat_feather = Maat_init(profile, logger);
+ _mgw_handle->Maat_feather = Maat_feather;
+ _mgw_handle->mgw_tun_handle_s = mgw_tun_init("tun_mgw", logger);
+ MESA_htable_handle ip2user_htable = mgw_utils_create_htable("ip2user_htable", _mgw_handle->htable_opts_s, (void *)ip2user_htable_free_data_cb, NULL);
+ if(ip2user_htable == NULL)
+ {
+ MGW_LOG_ERROR(logger, "Failed at create ip2user_htable");
+ exit(EXIT_FAILURE);
+ }
+ _mgw_handle->nat_handle_s = nat_init(ip2user_htable, logger, _htable_opts);
pthread_t thread_id;
- int rtn = pthread_create(&thread_id, NULL, thread_vpn_monitor, NULL);
+ struct vpn_monitor_args args = {.ip2user_htable = ip2user_htable, .logger = logger};
+ int rtn = pthread_create(&thread_id, NULL, thread_vpn_monitor, (void *)&args);
if(unlikely(rtn != 0))
{
- MGW_LOG_ERROR(g_mgw_ctx.logger, "Failed at creating thread_vpn_monitor");
+ MGW_LOG_ERROR(logger, "Failed at creating thread_vpn_monitor");
exit(EXIT_FAILURE);
}
+ struct ip_mgr_handle * _ip_mgr_handle = ip_mgr_init(logger, Maat_feather, _htable_opts);
+ if(unlikely(_ip_mgr_handle == NULL))
+ {
+ MGW_LOG_ERROR(logger, "Failed at init_ip_mgr");
+ exit(EXIT_FAILURE);
+ }
+ _mgw_handle->ip_mgr_handle_s = _ip_mgr_handle;
+ return _mgw_handle;
}
-static void mgw_destroy()
+static void mgw_destroy(struct mgw_handle *_mgw_handle)
{
- MESA_destroy_runtime_log_handle(g_mgw_ctx.logger);
- Maat_burn_feather(g_mgw_ctx.Maat_feather);
+ MESA_destroy_runtime_log_handle(_mgw_handle->logger);
+ Maat_burn_feather(_mgw_handle->Maat_feather);
}
-static void mgw_run()
+static void mgw_run(struct mgw_handle *handle)
{
while(1)
{
-
+ char buff[MGW_PACKET_MAX];
+ int len = mgw_tun_read(handle->mgw_tun_handle_s, buff, MGW_PACKET_MAX);
+ nat_src_convert(handle->nat_handle_s, handle->ip_mgr_handle_s, buff, len);
}
}
int main(int argc, char* argv[])
{
- mgw_init();
- mgw_run();
-}
-
-#ifdef __cplusplus
+ struct mgw_handle *handle = mgw_init();
+ mgw_run(handle);
}
-#endif
diff --git a/access/src/nat.cpp b/access/src/nat.cpp
new file mode 100644
index 0000000..a9a9543
--- /dev/null
+++ b/access/src/nat.cpp
@@ -0,0 +1,384 @@
+#include "mgw_utils.h"
+#include "nat.h"
+#include "ip_mgr.h"
+//hash表超时时间设为0,不超时
+// hash表 value 为malloc
+
+struct nat_handle
+{
+ void *logger;
+ struct htable_opts* htable_opts_s;
+ MESA_htable_handle ip2user_htable; // should be thread-safe
+ MESA_htable_handle snat_htable;
+ MESA_htable_handle dnat_htable;
+ int access_id;
+};
+
+struct session
+{
+ uint32_t sip;
+ uint16_t sport;
+ uint32_t dip;
+ uint16_t dport;
+ uint8_t proto;
+};
+
+struct ip_port_pair
+{
+ uint32_t ip;
+ uint16_t port;
+};
+
+struct candidate_port
+{
+ unsigned int access_id : 2;
+ unsigned int random : 6;
+ unsigned int hash : 8;
+};
+
+struct nat_ctx
+{
+ void *logger;
+ char *buff;
+ int len;
+ MESA_htable_handle ip2user_htable;
+};
+
+// input: ip packet
+// output: session <sip, dip, sport, dport, proto>
+static int sess_get_from_packet(const char *buff, int len, struct session *sess)
+{
+ if(len < 20)
+ {
+ return -1;
+ }
+ struct iphdr *_iphdr = (struct iphdr *)buff;
+ int iphdr_len = _iphdr->ihl * 4;
+ sess->sip = ntohl(_iphdr->saddr);
+ sess->dip = ntohl(_iphdr->daddr);
+ sess->proto = _iphdr->protocol;
+ switch(sess->proto)
+ {
+ case PROTO_TCP:
+ {
+ if(len < 40)
+ {
+ return -1;
+ }
+ struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len);
+ sess->sport = ntohs(_tcphdr->source);
+ sess->dport = ntohs(_tcphdr->dest);
+ break;
+ }
+ case PROTO_UDP:
+ {
+ if(len < 28)
+ {
+ return -1;
+ }
+ struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len);
+ sess->sport = ntohs(_udphdr->source);
+ sess->dport = ntohs(_udphdr->dest);
+ break;
+ }
+ case PROTO_ICMP:
+ {
+ if(len < 28)
+ {
+ return -1;
+ }
+ break;
+ }
+ default:
+ return -1;
+ break;
+ }
+ return 0;
+}
+
+static int packet_src_replace(const char *buff, int len, struct ip_port_pair *pair)
+{
+ struct iphdr *_iphdr = (struct iphdr *)buff;
+ int iphdr_len = _iphdr->ihl * 4;
+ _iphdr->saddr = pair->ip;
+ switch(_iphdr->protocol)
+ {
+ case PROTO_TCP:
+ {
+ struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len);
+ _tcphdr->source = pair->port;
+ break;
+ }
+ case PROTO_UDP:
+ {
+ struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len);
+ _udphdr->source = pair->port;
+ break;
+ }
+ case PROTO_ICMP:
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int packet_dest_replace(const char *buff, int len, struct ip_port_pair *pair)
+{
+ struct iphdr *_iphdr = (struct iphdr *)buff;
+ int iphdr_len = _iphdr->ihl * 4;
+ _iphdr->daddr = pair->ip;
+ switch(_iphdr->protocol)
+ {
+ case PROTO_TCP:
+ {
+ struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len);
+ _tcphdr->dest = pair->port;
+ break;
+ }
+ case PROTO_UDP:
+ {
+ struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len);
+ _udphdr->dest = pair->port;
+ break;
+ }
+ case PROTO_ICMP:
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void snat_htable_data_free_cb(void *data)
+{
+ FREE(&data);
+}
+
+static void dnat_htable_data_free_cb(void *data)
+{
+ FREE(&data);
+}
+
+
+struct nat_handle * nat_init(MESA_htable_handle _ip2user_htable, void *logger, struct htable_opts* opts)
+{
+ struct nat_handle *handle = ALLOC(struct nat_handle, 1);
+ handle->logger = logger;
+ handle->ip2user_htable = _ip2user_htable;
+ handle->htable_opts_s = opts;
+ handle->snat_htable = mgw_utils_create_htable("snat_htable", opts, (void *)snat_htable_data_free_cb, NULL);
+ handle->dnat_htable = mgw_utils_create_htable("dnat_htable", opts, (void *)dnat_htable_data_free_cb, NULL);
+ handle->access_id = 0;
+ return handle;
+}
+
+void nat_destroy(struct nat_handle *handle)
+{
+ MESA_htable_destroy(handle->snat_htable, snat_htable_data_free_cb);
+ MESA_htable_destroy(handle->dnat_htable, dnat_htable_data_free_cb);
+ FREE(&handle);
+}
+
+static long snat_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg)
+{
+ struct ip_port_pair *pair = (struct ip_port_pair *)user_arg;
+ if(data != NULL)
+ {
+ struct ip_port_pair *_data = (struct ip_port_pair *)data;
+ pair->ip = _data->ip;
+ pair->port = _data->port;
+ return HTABLE_KEY_EXISTED;
+ }
+ else
+ {
+ return HTABLE_KEY_NOT_EXISTED;
+ }
+}
+
+static long dnat_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg)
+{
+ struct ip_port_pair *pair = (struct ip_port_pair *)user_arg;
+ if(data != NULL)
+ {
+ struct ip_port_pair *_data = (struct ip_port_pair *)data;
+ pair->ip = _data->ip;
+ pair->port = _data->port;
+ return HTABLE_KEY_EXISTED;
+ }
+ else
+ {
+ return HTABLE_KEY_NOT_EXISTED;
+ }
+}
+
+static uint16_t get_candidate_port(int access_id, struct session *sess)
+{
+ struct candidate_port *port = ALLOC(struct candidate_port, 1);
+ port->access_id = 0;
+ unsigned int random = mgw_utils_get_random(64);
+ port->random = random;
+ unsigned int hash = (sess->sip)^(sess->dip)^(sess->sport)^(sess->dport)^(sess->proto);
+ hash &= 0xff;
+ port->hash = hash;
+ u_int16_t _port = *((u_int16_t *)port);
+ return _port;
+}
+
+static struct ip_port_pair * snat_pair_get(struct nat_handle *handle, struct ip_mgr_handle *_ip_mgr_handle, const char *user_name, struct session *snat_key)
+{
+ int retry_times = 10;
+ void *logger = handle->logger;
+ for(int i = 0; i < retry_times; i++)
+ {
+ struct cand_ip* _cand_ip = ip_mgr_candidata_ip_get(_ip_mgr_handle, user_name);
+ u_int16_t port = get_candidate_port(handle->access_id, snat_key);
+ struct session dnat_key;
+ dnat_key.sip = snat_key->dip;
+ dnat_key.sport = snat_key->dport;
+ dnat_key.proto = snat_key->proto;
+ dnat_key.dip = _cand_ip->ip;
+ dnat_key.dport = port;
+ long dnat_cb_rtn = -1;
+ struct ip_port_pair pair;
+ MESA_htable_search_cb(handle->dnat_htable, (const unsigned char *)(&dnat_key), sizeof(dnat_key), dnat_htable_query_cb, (void *)(&pair), &dnat_cb_rtn);
+ if(dnat_cb_rtn == HTABLE_KEY_EXISTED)
+ {
+ MGW_LOG_INFO(logger, "Select ip and port conflict, retry times is %d", i);
+ continue;
+ }
+ else
+ {
+ struct ip_port_pair *selected_pair = ALLOC(struct ip_port_pair, 1);
+ selected_pair->ip = _cand_ip->ip;
+ _cand_ip->reference ++;
+ selected_pair->port = port;
+ return selected_pair;
+ }
+ }
+ MGW_LOG_INFO(logger, "Failed to find ip and port, retry times is %d", retry_times - 1);
+ return NULL;
+}
+
+int nat_src_convert(struct nat_handle *handle, struct ip_mgr_handle *_ip_mgr_handle, char *buff, int len)
+{
+ void *logger = handle->logger;
+ //get session
+ struct session snat_key;
+ int rtn = sess_get_from_packet(buff, len, &snat_key);
+ if(rtn == -1)
+ {
+ MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len);
+ return NAT_COVERT_FAILURE;
+ }
+ //query snat_htable,get ip_port pair
+ long snat_cb_rtn = -1;
+ struct ip_port_pair snat_value;
+ MESA_htable_search_cb(handle->snat_htable, (const unsigned char *)(&snat_key), sizeof(snat_key), snat_htable_query_cb, (void *)(&snat_value), &snat_cb_rtn);
+ bool ip_is_valid = ip_mgr_candidate_ip_verify(_ip_mgr_handle, snat_value.ip);
+ if(snat_cb_rtn == HTABLE_KEY_EXISTED && ip_is_valid == true)
+ {
+ MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "ip2user_htable",
+ mgw_utils_inet_ntoa(snat_key.sip), snat_key.sport, mgw_utils_inet_ntoa(snat_key.dip), snat_key.dport, snat_key.proto, mgw_utils_inet_ntoa(snat_value.ip), snat_value.port);
+ packet_src_replace(buff, len, &snat_value);
+ }
+ else
+ {
+ //if session exists in sant but ip is valid. del session from snat and dnat
+ if(snat_cb_rtn == HTABLE_KEY_EXISTED)
+ {
+ int rtn = MESA_htable_del(handle->snat_htable, (const unsigned char *)(&snat_key), sizeof(snat_key), NULL);
+ // data may be freed because of expire
+ if(rtn < 0 && rtn != MESA_HTABLE_RET_NOT_FOUND)
+ {
+ MGW_LOG_ERROR(handle->logger, "MESA_htable: failed at del, errno is %d, table is %s, key is <%s:%d %s,%d, %d>", rtn, "snat_htable",
+ mgw_utils_inet_ntoa(snat_key.sip), snat_key.sport, mgw_utils_inet_ntoa(snat_key.dip), snat_key.dport, snat_key.proto);
+ return NAT_COVERT_FAILURE;;
+ }
+ struct session dnat_key;
+ dnat_key.sip = snat_key.dip;
+ dnat_key.sport = snat_key.dport;
+ dnat_key.dip = snat_value.ip;
+ dnat_key.dport = snat_value.port;
+ dnat_key.proto = snat_key.proto;
+ rtn = MESA_htable_del(handle->dnat_htable, (const unsigned char *)(&dnat_key), sizeof(dnat_key), NULL);
+ if(rtn < 0 && rtn != MESA_HTABLE_RET_NOT_FOUND)
+ {
+ MGW_LOG_ERROR(handle->logger, "MESA_htable: failed at del, errno is %d, table is %s, key is <%s:%d %s,%d, %d>", rtn, "dnat_htable",
+ mgw_utils_inet_ntoa(dnat_key.sip), dnat_key.sport, mgw_utils_inet_ntoa(snat_key.dip), dnat_key.dport, dnat_key.proto);
+ return NAT_COVERT_FAILURE;;
+ }
+ }
+ uint32_t sip = snat_key.sip;
+ char *user_name;
+ user_name = (char *)MESA_htable_search(handle->ip2user_htable, (const unsigned char *)(&sip), sizeof(sip));
+ if(user_name != NULL)
+ {
+ struct ip_port_pair *snat_value = snat_pair_get(handle, _ip_mgr_handle, user_name, &snat_key);
+ if(snat_value == NULL)
+ {
+ return NAT_COVERT_FAILURE;
+ }
+ //add sess to snat, dnat
+ int rtn = MESA_htable_add(handle->snat_htable, (const unsigned char *)(&snat_key), sizeof(snat_key), (const void*)snat_value);
+ if(rtn < 0)
+ {
+ MGW_LOG_INFO(logger, "MESA_htable: add to %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "snat_htable",
+ mgw_utils_inet_ntoa(snat_key.sip), snat_key.sport, mgw_utils_inet_ntoa(snat_key.dip), snat_key.dport, snat_key.proto, mgw_utils_inet_ntoa(snat_value->ip), snat_value->port);
+ return NAT_COVERT_FAILURE;
+ }
+ struct session dnat_key;
+ dnat_key.sip = snat_key.dip;
+ dnat_key.sport = snat_key.dport;
+ dnat_key.dip = snat_value->ip;
+ dnat_key.dport = snat_value->port;
+ dnat_key.proto = snat_key.proto;
+ struct ip_port_pair *dnat_value = ALLOC(struct ip_port_pair, 1);
+ dnat_value->ip = snat_key.sip;
+ dnat_value->port = snat_key.sport;
+ rtn = MESA_htable_add(handle->dnat_htable, (const unsigned char *)(&dnat_key), sizeof(dnat_key), (const void*)dnat_value);
+ if(rtn < 0)
+ {
+ MGW_LOG_INFO(logger, "MESA_htable: add to %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "dnat_htable",
+ mgw_utils_inet_ntoa(dnat_key.sip), dnat_key.sport, mgw_utils_inet_ntoa(dnat_key.dip), dnat_key.dport, dnat_key.proto, mgw_utils_inet_ntoa(dnat_value->ip), dnat_value->port);
+ return NAT_COVERT_FAILURE;
+ }
+ packet_src_replace(buff, len, dnat_value);
+ return NAT_COVERT_SUCCESS;
+ }
+ else
+ {
+ MGW_LOG_ERROR(logger, "Failed at find user_name, ip %s", mgw_utils_inet_ntoa(sip));
+ return NAT_COVERT_FAILURE;
+ }
+ }
+}
+
+int nat_dest_convert(struct nat_handle *handle, char *buff, int len)
+{
+ void *logger = handle->logger;
+ //get session
+ struct session *sess = ALLOC(struct session, 1);
+ int rtn = sess_get_from_packet(buff, len, sess);
+ if(rtn == -1)
+ {
+ MGW_LOG_ERROR(logger, "Failed at sess_get_from_packet, packet len is %d", len);
+ return NAT_COVERT_FAILURE;
+ }
+ //query dnat,get ip and port
+ long dnat_cb_rtn = -1;
+ struct ip_port_pair pair;
+ MESA_htable_search_cb(handle->dnat_htable, (const unsigned char *)(&sess), sizeof(sess), dnat_htable_query_cb, (void *)(&pair), &dnat_cb_rtn);
+ if(dnat_cb_rtn == HTABLE_KEY_EXISTED)
+ {
+ MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "dnat_htable",
+ mgw_utils_inet_ntoa(sess->sip), sess->sport, mgw_utils_inet_ntoa(sess->dip), sess->dport, sess->proto, mgw_utils_inet_ntoa(pair.ip), pair.port);
+ packet_dest_replace(buff, len, &pair);
+ }
+ else
+ {
+ MGW_LOG_ERROR(logger, "MESA_htable: key not existed, table is %s, key is <%s:%d %s,%d, %d>", "dnat_htable",
+ mgw_utils_inet_ntoa(sess->sip), sess->sport, mgw_utils_inet_ntoa(sess->dip), sess->dport, sess->proto);
+ return NAT_COVERT_FAILURE;
+ }
+}
diff --git a/access/src/vpn_monitor.cpp b/access/src/vpn_monitor.cpp
index 74fe11d..c0b94c5 100644
--- a/access/src/vpn_monitor.cpp
+++ b/access/src/vpn_monitor.cpp
@@ -1,128 +1,209 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <pthread.h>
-#include "MESA/MESA_prof_load.h"
-#include "MESA/MESA_handle_logger.h"
-#include "MESA/MESA_htable.h"
#include "mgw_utils.h"
+#include "vpn_monitor.h"
struct hub_info
{
char name[MGW_SYMBOL_MAX];
char passwd[MGW_SYMBOL_MAX];
-};
+ unsigned int dhcp_begin_ip;
+ unsigned int dhcp_end_ip;
+}hub_info_t;
#define MAX_HUB_NUM 20
-struct vpn_monitor_ctx
+struct vpn_monitor_handle
{
- char vpn_server_ip[MGW_SYMBOL_MAX];
- int vpn_server_port;
- char vpn_server_passwd[MGW_SYMBOL_MAX];
+ void *logger;
+ char server_ip[MGW_SYMBOL_MAX];
+ int server_port;
+ char server_passwd[MGW_SYMBOL_MAX];
struct hub_info hubs[MAX_HUB_NUM];
int hub_num;
MESA_htable_handle ip2user_htable; // should be thread-safe
};
-static int __wrapper_MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, unsigned value)
-{
- int ret = MESA_htable_set_opt(table, opt_type, &value, (int)(sizeof(value)));
- assert(ret == 0);
- return ret;
-}
-static int __wrapper_MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, void * val, size_t len)
+void ip2user_htable_data_free_cb(void *data)
{
- int ret = MESA_htable_set_opt(table, opt_type, val, (int)len);
- if(unlikely(ret != 0))
- {
- MGW_LOG_ERROR("Failed at MESA_htable_set_opt, opt_type is %d", opt_type);
- }
- return ret;
+ FREE(&data);
}
-static MESA_htable_handle create_ip2user_table()
-{
- int ret = 0;
- unsigned max_num = slot_size * 4;
- MESA_htable_handle ip2user_htable = MESA_htable_born();
- __wrapper_MESA_htable_set_opt_int(htable, MHO_SCREEN_PRINT_CTRL, g_mgw_ctx._htable_opt->mho_screen_print_ctrl);
- __wrapper_MESA_htable_set_opt_int(htable, MHO_THREAD_SAFE, g_mgw_ctx._htable_opt->mho_thread_safe);
- __wrapper_MESA_htable_set_opt_int(htable, MHO_MUTEX_NUM, g_mgw_ctx._htable_opt->mho_mutex_num);
- __wrapper_MESA_htable_set_opt_int(htable, MHO_HASH_SLOT_SIZE, g_mgw_ctx._htable_opt->mho_hash_slot_size);
- __wrapper_MESA_htable_set_opt_int(htable, MHO_HASH_MAX_ELEMENT_NUM, g_mgw_ctx._htable_opt->mho_hash_slot_size * 4);
- __wrapper_MESA_htable_set_opt_int(htable, MHO_EXPIRE_TIME, g_mgw_ctx._htable_opt->mho_expire_time);
- __wrapper_MESA_htable_set_opt_int(htable, MHO_ELIMIMINATE_TYPE, HASH_ELIMINATE_ALGO_FIFO);
- ret = __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_FREE,
- (void *)ip2user_htable_free_data, sizeof(&ip2user_htable_free_data));
- //ret = __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_EXPIRE_NOTIFY,
- // (void *)key_keeper_verify_cb);
- ret = MESA_htable_mature(ip2user_htable);
- if(ret != 0)
- {
- MGW_LOG_ERROR("Failed at create ip2user_htable");
- exit(EXIT_FAILURE);
- }
- return ip2user_htable;
-}
-struct vpn_monitor_ctx * vpn_monitor_init()
+struct vpn_monitor_handle * vpn_monitor_init(void *args)
{
- struct vpn_monitor_ctx *ctx = ALLOC(struct vpn_monitor_ctx, 1);
- ctx->ip2user_htable = create_ip2user_table();
+ struct vpn_monitor_args *_args = (struct vpn_monitor_args *)args;
+ struct vpn_monitor_handle *handle = ALLOC(struct vpn_monitor_handle, 1);
+ handle->logger = _args->logger;
+ handle->ip2user_htable = _args->logger;
+ const char *profile = _args->profile;
const char *section = "vpn_server";
char hub_list_str[MGW_STRING_MAX];
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "vpn_server_ip", ctx->vpn_server_ip, sizeof(vpn_server_ip), "localhost");
- MESA_load_profile_int_def(g_mgw_ctx.profile, section, "vpn_server_port", &(ctx->vpn_server_port), 443);
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "vpn_server_passwd", ctx->vpn_server_passwd, sizeof(vpn_server_passwd), "111111");
- MESA_load_profile_string_def(g_mgw_ctx.profile, section, "hub_list", hub_list_str, sizeof(hub_list_str), "{NewHub0|111111}");
+ MESA_load_profile_string_def(profile, section, "server_ip", handle->server_ip, sizeof(handle->server_ip), "localhost");
+ MESA_load_profile_int_def(profile, section, "server_port", &(handle->server_port), 443);
+ MESA_load_profile_string_def(profile, section, "server_passwd", handle->server_passwd, sizeof(handle->server_passwd), "111111");
+ MESA_load_profile_string_def(profile, section, "hub_list", hub_list_str, sizeof(hub_list_str), "{NewHub0|111111}");
+ MGW_LOG_INFO(handle->logger, "MESA_prof_load, [%s]:\n server_ip: %s\n server_port: %d\n server_passwd: %s\n hub_list: %s",
+ "vpn_server", handle->server_ip, handle->server_port, handle->server_passwd, hub_list_str);
char *token;
char *rest = hub_list_str;
- ctx->hub_num = 0;
+ handle->hub_num = 0;
while((token = strtok_r(rest, ",", &rest)))
{
- //printf("token is %s\n", token);
- int len = strnlen(token, MGW_STRING_MAX);
- char *pos = strchr(token, '|');
- if(pos == NULL)
+ printf("token is %s\n", token);
+ char hub_name[MGW_SYMBOL_MAX];
+ char hub_passwd[MGW_SYMBOL_MAX];
+ char dhcp_begin_ip[MGW_SYMBOL_MAX];
+ char dhcp_end_ip[MGW_SYMBOL_MAX];
+ sscanf(token, "{%s %s %s %[^}]", hub_name, hub_passwd, dhcp_begin_ip, dhcp_end_ip);
+ strncpy(handle->hubs[handle->hub_num].name, hub_name, MGW_SYMBOL_MAX);
+ strncpy(handle->hubs[handle->hub_num].passwd, hub_passwd, MGW_SYMBOL_MAX);
+ unsigned int _dhcp_begin_ip = inet_network(dhcp_begin_ip);
+ if(_dhcp_begin_ip == INADDR_NONE)
{
- MGW_LOG_ERROR(g_mgw_ctx.logger, "Invalid hub conf, hub is %s", token);
+ MGW_LOG_ERROR(handle->logger, "Invalid dhcp_begin_ip: %s", dhcp_begin_ip);
continue;
}
- strncpy(ctx->hubs[i].name, token + 1, pos - token - 1);
- strncpy(ctx->hubs[i].passwd, pos + 1, len - 2 - (pos - token));
- ctx->hubs.num ++;
- }
- int i = 0;
- for(i = 0; i < ctx->hub_num; i++)
- {
- printf("Hub: name is %s, passwd is %s\n", ctx->hubs[i].name, ctx->hubs[i].passwd);
+ handle->hubs[handle->hub_num].dhcp_begin_ip = _dhcp_begin_ip;
+ unsigned int _dhcp_end_ip = inet_network(dhcp_end_ip);
+ //printf("_dhcp_end_ip is %d\n", _dhcp_end_ip);
+ if(_dhcp_end_ip == INADDR_NONE)
+ {
+ MGW_LOG_ERROR(handle->logger, "Invalid dhcp_end_ip: %s", dhcp_end_ip);
+ continue;
+ }
+ handle->hubs[handle->hub_num].dhcp_end_ip = _dhcp_end_ip;
+ handle->hub_num ++;
}
- return ctx;
+ return handle;
}
-void * vpn_monitor_destroy(struct vpn_monitor_ctx *ctx)
+void * vpn_monitor_destroy(struct vpn_monitor_handle *handle)
{
+ FREE(&handle);
+}
+static long ip2user_cb_to_del_key(void *data, const uchar *key, uint size, void *user_arg)
+{
+ unsigned char _key[MGW_SYMBOL_MAX];
+ strncpy((char *)_key, (char *)key, size);
+ _key[size] = '\0';
+ struct vpn_monitor_handle *handle = (struct vpn_monitor_handle *)user_arg;
+ if(data != NULL)
+ {
+ MGW_LOG_INFO(handle->logger, "MESA_htable: key existed, table is %s, key is %s", "ip2user_htable", _key);
+ int rtn = MESA_htable_del(handle->ip2user_htable, key, size, ip2user_htable_data_free_cb);
+ if(rtn != 0)
+ {
+ MGW_LOG_ERROR(handle->logger, "MESA_htable: failed at del, errno is %d, table is %s, key is %s", rtn, "ip2user_htable", _key);
+ return HTABLE_QUERY_CB_FAILURE;
+ }
+ MGW_LOG_INFO(handle->logger, "MESA_htable: succeed at del, table is %s, key is %s", "ip2user_htable", _key);
+ }
+ return HTABLE_QUERY_CB_SUCCESS;
}
-static void get_ip2user_by_vpncmd(const char *vpn_server_ip, int vpn_server_port, const char *vpn_server_passwd, const char *hub_name, const char *hub_passwd)
+
+static void get_ip2user_by_vpncmd(struct vpn_monitor_handle *handle)
{
- char vpncmd_get_sessions[MGW_STRING_MAX];
- char vpncmd_get_iptables[MGW_STRING_MAX];
- snprintf(vpncmd_get_sessions, MGW_STRING_MAX, "vpncmd %s:%d /SERVER /PASSWORD:%s /HUB:%s /PASSWORD:%s /CSV /CMD SessionList",
- vpn_server_ip, vpn_server_port, vpn_server_passwd, hub_name, hub_passwd);
- snprintf(vpncmd_get_iptables, MGW_STRING_MAX, "vpncmd %s:%d /SERVER /PASSWORD:%s /HUB:%s /PASSWORD:%s /CSV /CMD IPTable",
- vpn_server_ip, vpn_server_port, vpn_server_passwd, hub_name, hub_passwd);
+ const char *server_ip = handle->server_ip;
+ int server_port = handle->server_port;
+ const char *server_passwd = handle->server_passwd;
+ char get_sessions_cmd[MGW_STRING_MAX];
+ char get_iptables_cmd[MGW_STRING_MAX];
+ char buff[MGW_STRING_MAX];
+ int i;
+ for(i = 0; i < handle->hub_num; i++)
+ {
+ const char *hub_name = handle->hubs[i].name;
+ const char *hub_passwd = handle->hubs[i].passwd;
+ unsigned int dhcp_begin_ip = handle->hubs[i].dhcp_begin_ip;
+ unsigned int dhcp_end_ip = handle->hubs[i].dhcp_end_ip;
+ snprintf(get_sessions_cmd, MGW_STRING_MAX, "vpncmd %s:%d /SERVER /PASSWORD:%s /HUB:%s /PASSWORD:%s /CSV /CMD SessionList",
+ server_ip, server_port, server_passwd, hub_name, hub_passwd);
+ snprintf(get_iptables_cmd, MGW_STRING_MAX, "vpncmd %s:%d /SERVER /PASSWORD:%s /HUB:%s /PASSWORD:%s /CSV /CMD IPTable",
+ server_ip, server_port, server_passwd, hub_name, hub_passwd);
+
+ //get_iptables_cmd
+ printf("get_iptables_cmd: %s\n", get_iptables_cmd);
+ FILE *get_iptables_fp = popen(get_iptables_cmd, "r");
+ if(get_iptables_fp == NULL)
+ {
+ MGW_LOG_ERROR(handle->logger, "Failed at popen, cmd is %s", get_iptables_cmd);
+ return;
+ }
+ fgets(buff, MGW_STRING_MAX, get_iptables_fp);
+ if(buff == NULL)
+ {
+ MGW_LOG_ERROR(handle->logger, "Failed at get_iptables_cmd: %s", "result is null");
+ return;
+ }
+ if(strstr(buff, "Error occurred") != NULL)
+ {
+ fgets(buff, MGW_STRING_MAX, get_iptables_fp);
+ MGW_LOG_ERROR(handle->logger, "Failed at get_iptables_cmd: %s", buff);
+ return;
+ }
+ //ID,Session Name,IP Address,Created at,Updated at,Location
+ //1549233234,SID-TESTING10-182,192.168.11.167,2018-11-05 15:02:30,2018-11-05 15:29:02,On 'localhost.localdomain'
+ //user_name不区分大小写,不能包含-,数据库中一律存小写
+ while(fgets(buff, MGW_STRING_MAX, get_iptables_fp))
+ {
+ char id[MGW_SYMBOL_MAX];
+ char sess_name[MGW_SYMBOL_MAX];
+ char dhcp_ip[MGW_SYMBOL_MAX];
+ sscanf(buff, "%[^,],%[^,],%[^,]", id, sess_name, dhcp_ip);
+
+ //get ip and user_name
+ char *user_name = ALLOC(char, MGW_SYMBOL_MAX);
+ sscanf(sess_name, "SID-%[^-]", user_name);
+ //change to lower case
+ int i;
+ for(i = 0; i < strnlen(user_name, MGW_SYMBOL_MAX); i ++)
+ {
+ if(user_name[i] >= 'A' && user_name[i] <= 'Z')
+ {
+ user_name[i] = user_name[i] - 'A' + 'a';
+ }
+ }
+
+ char ip[MGW_SYMBOL_MAX];
+ sscanf(dhcp_ip, "%s", ip);
+
+ //find ip in dhcp range
+ unsigned int _ip = inet_network(ip);
+ if(_ip == INADDR_NONE)
+ {
+ MGW_LOG_ERROR(handle->logger, "Invalid dhcp_ip: %s", ip);
+ continue;
+ }
+ if(_ip > dhcp_end_ip || _ip < dhcp_begin_ip)
+ {
+ MGW_LOG_INFO(handle->logger, "Not in dhcp range, ip is %s", ip);
+ continue;
+ }
+ //set ip2user
+ long cb_rtn = -1;
+ size_t key_size = sizeof(_ip);
+ //printf("serach: key is %s\n", ip);
+ MESA_htable_search_cb(handle->ip2user_htable, (const unsigned char *)(&_ip), key_size, ip2user_cb_to_del_key, (void *)handle, &cb_rtn);
+ int rtn = MESA_htable_add(handle->ip2user_htable, (const unsigned char *)(&_ip), key_size, user_name);
+ if(rtn < 0)
+ {
+ MGW_LOG_ERROR(handle->logger, "MESA_htable: failed at add, table is %s, key is %s, value is %s", "ip2user_htable", ip, user_name);
+ continue;
+ }
+ MGW_LOG_INFO(handle->logger, "MESA_htable: succeed at add, table is %s, key is %s, value is %s", "ip2user_htable", ip, user_name);
+ }
+ }
}
-void * thread_vpn_monitor(void* arg)
+
+void * thread_vpn_monitor(void* args)
{
- struct vpn_monitor_ctx ctx = vpn_monitor_init();
- g_mgw_ctx._vpn_monitor_ctx = ctx;
- sleep(10);
- for(i = 0; i < ctx.hub_num; i++)
+ struct vpn_monitor_handle *handle = vpn_monitor_init(args);
+ while(1)
{
- get_ip2user_by_vpncmd(ctx->vpn_server_ip, ctx->vpn_server_port, ctx->vpn_server_passwd, ctx->hubs[i].name, ctx->hubs.passwd);
- }
+ sleep(3);
+ printf("vpn monitor--------------\n");
+ get_ip2user_by_vpncmd(handle);
+ }
} \ No newline at end of file
diff --git a/access/test/test_MESA_htable.cpp b/access/test/test_MESA_htable.cpp
new file mode 100644
index 0000000..3355e1a
--- /dev/null
+++ b/access/test/test_MESA_htable.cpp
@@ -0,0 +1,47 @@
+
+#include "mgw_utils.h"
+
+static struct htable_opts * htable_opt_init(const char* profile, void *logger)
+{
+ struct htable_opts* _htable_opts = ALLOC(struct htable_opts, 1);
+ const char *section = "htable_opt";
+ MESA_load_profile_int_def(profile, section, "mho_screen_print_ctrl", &(_htable_opts->mho_screen_print_ctrl), 0);
+ MESA_load_profile_int_def(profile, section, "mho_thread_safe", &(_htable_opts->mho_thread_safe), 1);
+ MESA_load_profile_int_def(profile, section, "mho_mutex_num", &(_htable_opts->mho_mutex_num), 16);
+ MESA_load_profile_int_def(profile, section, "mho_hash_slot_size", &(_htable_opts->mho_hash_slot_size), 16);
+ MESA_load_profile_int_def(profile, section, "mho_expire_time", &(_htable_opts->mho_expire_time), 0);
+ MGW_LOG_INFO(logger, "MESA_prof_load, [%s]:\n mho_screen_print_ctrl: %d\n mho_thread_safe: %d\n mho_mutex_num: %d\n mho_hash_slot_size: %d\n mho_expire_time: %d",
+ "htable_opt", _htable_opts->mho_screen_print_ctrl, _htable_opts->mho_thread_safe, _htable_opts->mho_mutex_num, _htable_opts->mho_hash_slot_size, _htable_opts->mho_expire_time);
+ return _htable_opts;
+}
+
+void test_htable_data_free_cb(void *data)
+{
+ free(data);
+ //FREE(&data);
+}
+
+int main()
+{
+ /*
+ const char *profile = "./conf/mgw.conf";
+ void *logger = MESA_create_runtime_log_handle("./log/mgw.log", RLOG_LV_DEBUG);
+ struct htable_opts * opts = htable_opt_init(profile, logger);
+ MESA_htable_handle test_htable = create_htable("test", opts, (void *)test_htable_data_free_cb, NULL);
+ const char ip[MGW_SYMBOL_MAX] = "192.168.1.1";
+ int key_size = strnlen(ip, MGW_SYMBOL_MAX);
+ char *user_name = ALLOC(char, MGW_SYMBOL_MAX);
+ strncpy(user_name, "leo", MGW_SYMBOL_MAX);
+ //int rtn = MESA_htable_add(test_htable, (const unsigned char *)ip, key_size, user_name);
+ //printf("MESA_htable_add: ret is %d\n", rtn);
+ int rtn = MESA_htable_del(test_htable, (const unsigned char *)ip, key_size, NULL);
+ printf("MESA_htable_del: ret is %d\n", rtn);
+ */
+ //char ip[MGW_SYMBOL_MAX] = "1.0.0.0";
+ //uint32_t _ip = inet_addr(ip);
+ char *ip;
+ uint32_t _ip = 1;
+ ip = inet_ntoa(*(struct in_addr *)&_ip);
+ printf("_ip is %s\n", ip);
+}
+
diff --git a/access/test/test_maat_redis.cpp b/access/test/test_maat_redis.cpp
index 2fb1b34..70d056c 100644
--- a/access/test/test_maat_redis.cpp
+++ b/access/test/test_maat_redis.cpp
@@ -3,10 +3,6 @@
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
-#include "MESA/MESA_prof_load.h"
-#include "MESA/MESA_handle_logger.h"
-#include "MESA/Maat_rule.h"
-#include "MESA/Maat_command.h"
#include "mgw_utils.h"
@@ -15,12 +11,6 @@ extern "C"
{
#endif
-struct mgw_ctx
-{
- void* logger;
- const char *profile;
- Maat_feather_t Maat_feather;
-};
struct mgw_ctx g_mgw_ctx;
void wrapped_Maat_set_feather_opt(Maat_feather_t feather, enum MAAT_INIT_OPT type, const void* value, int size)
diff --git a/access/src/tun.cpp b/access/test/test_tun.cpp
index 0a57491..4a15011 100644
--- a/access/src/tun.cpp
+++ b/access/test/test_tun.cpp
@@ -1,101 +1,110 @@
-#include <stdio.h>
-#include <string.h>
-
-#include <linux/if_tun.h>
-#include <netinet/in.h>
-#include<fcntl.h>
-
-#include<linux/udp.h>
-
-#include "tun.h"
-
-/**************************************************************************
- * tun_alloc: create a tun fd,and set tun param . *
- * return : a tun fd *
- **************************************************************************/
-int tun_alloc(char *dev)
-{
- struct ifreq ifr;
- int fd, err;
-
- if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
- {
- printf("open function errno %d is %s\n",errno,strerror(errno));
- assert(0);
- }
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;//不包含tun包信息
-
- if (*dev)
- {
- strncpy(ifr.ifr_name, dev, IFNAMSIZ);
- }
-
- if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
- {
- printf("ioctl function err is %d,errno %d is %s\n",err,errno,strerror(errno));
- close(fd);
- assert(0);
- }
- strcpy(dev, ifr.ifr_name);
-
- return fd;
-}
-
-/**************************************************************************
- * read_from_tun: read data from tun , and puts them into buffer. *
- * return : read bytes *
- **************************************************************************/
-int read_from_tun(int tun_fd, char *recv_ip_pkts,size_t ip_pkt_len)
- {
- int recv_ip_len = 0;
- recv_ip_len = read(tun_fd, recv_ip_pkts, ip_pkt_len);
- if(recv_ip_len < 0)
- {
- close(tun_fd);
- printf("read function errno %d is %s\n",errno, strerror(errno));
- assert(0);
- }
- else
- {
- return recv_ip_len;
- }
-
-
-
- }
-
-
- /**************************************************************************
- * write_to_tun: write data to tun *
- * return:write bytes *
- **************************************************************************/
-int write_to_tun(int tun_fd, char *send_ip_pkts, int send_ip_len)
- {
- assert(send_ip_pkts !=NULL);
- assert(send_ip_len > 0);
-
- int cur_snd_ip_len = 0 ;
-
- cur_snd_ip_len = write(tun_fd, send_ip_pkts, send_ip_len);
- if(cur_snd_ip_len < 0)
- {
- printf(" send ip pkts errno = %d, content is %s\n",errno, strerror(errno));
- assert(0);
- }
- else
- {
- if(cur_snd_ip_len < send_ip_len)
- {
- close(tun_fd);
- printf("the ip data can not send completely!\n");
- assert(0);
- }
- else
- {
- return cur_snd_ip_len;
- }
-
- }
- }
+
+#ifndef TUN_H_INCLUDED
+#define TUN_H_INCLUDED
+#endif
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <linux/if_ether.h>
+#include <stddef.h>
+#include <net/if.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <linux/if_tun.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+
+#include "mgw_utils.h"
+
+/**************************************************************************
+ * tun_alloc: create a tun fd,and set tun param . *
+ * return : a tun fd *
+ **************************************************************************/
+int tun_alloc(char *dev)
+{
+ struct ifreq ifr;
+ int fd, err;
+ if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+ {
+ printf("open function errno %d is %s\n",errno,strerror(errno));
+ assert(0);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TUN | IFF_NO_PI;//不包含tun包信息
+ if (*dev)
+ {
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+ if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
+ {
+ printf("ioctl function err is %d,errno %d is %s\n",err,errno,strerror(errno));
+ close(fd);
+ assert(0);
+ }
+ strcpy(dev, ifr.ifr_name);
+ return fd;
+}
+
+/**************************************************************************
+ * read_from_tun: read data from tun , and puts them into buffer. *
+ * return : read bytes *
+ **************************************************************************/
+int read_from_tun(int tun_fd, char *recv_ip_pkts,size_t ip_pkt_len)
+ {
+ int recv_ip_len = 0;
+ recv_ip_len = read(tun_fd, recv_ip_pkts, ip_pkt_len);
+ if(recv_ip_len < 0)
+ {
+ close(tun_fd);
+ printf("read function errno %d is %s\n",errno, strerror(errno));
+ assert(0);
+ }
+ else
+ {
+ return recv_ip_len;
+ }
+ }
+
+
+ /**************************************************************************
+ * write_to_tun: write data to tun *
+ * return:write bytes *
+ **************************************************************************/
+int write_to_tun(int tun_fd, char *send_ip_pkts, int send_ip_len)
+ {
+ assert(send_ip_pkts !=NULL);
+ assert(send_ip_len > 0);
+ int cur_snd_ip_len = 0 ;
+ cur_snd_ip_len = write(tun_fd, send_ip_pkts, send_ip_len);
+ if(cur_snd_ip_len < 0)
+ {
+ printf(" send ip pkts errno = %d, content is %s\n",errno, strerror(errno));
+ assert(0);
+ }
+ else
+ {
+ if(cur_snd_ip_len < send_ip_len)
+ {
+ close(tun_fd);
+ printf("the ip data can not send completely!\n");
+ assert(0);
+ }
+ else
+ {
+ return cur_snd_ip_len;
+ }
+ }
+ }
+
+int main(int argc, char* argv[])
+{
+ char dev[MGW_SYMBOL_MAX] = "tun_mgw";
+ int fd = tun_alloc(dev);
+ char buff[1500];
+ int ret;
+ while((ret = read_from_tun(fd, buff, sizeof(buff))) > 0)
+ {
+ printf("ret is %d\n", ret);
+ printf("buff is %s\n", buff);
+ }
+} \ No newline at end of file
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 69637dd..acc463f 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -1,3 +1,3 @@
-add_library(common src/mgw_utils.cpp)
+add_library(common src/mgw_utils.cpp src/mgw_tun.cpp)
target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
target_link_libraries(common MESA_handle_logger) \ No newline at end of file
diff --git a/common/include/mgw_socket.h b/common/include/mgw_socket.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/include/mgw_socket.h
diff --git a/common/include/mgw_tun.h b/common/include/mgw_tun.h
new file mode 100644
index 0000000..76ef0d5
--- /dev/null
+++ b/common/include/mgw_tun.h
@@ -0,0 +1,11 @@
+#pragma once
+
+struct mgw_tun_handle;
+
+struct mgw_tun_handle * mgw_tun_init(char *dev, void *logger);
+
+int mgw_tun_read(struct mgw_tun_handle *handle, char *recv_ip_pkts, size_t ip_pkt_len);
+
+int mgw_tun_write(int tun_fd, char *send_ip_pkts, int send_ip_len);
+
+void mgw_tun_destroy(struct mgw_tun_handle *handle); \ No newline at end of file
diff --git a/common/include/mgw_utils.h b/common/include/mgw_utils.h
index 8797a36..1dc32f2 100644
--- a/common/include/mgw_utils.h
+++ b/common/include/mgw_utils.h
@@ -1,12 +1,28 @@
#pragma once
-#include <MESA/MESA_handle_logger.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include "MESA/MESA_handle_logger.h"
+#include "MESA/MESA_htable.h"
+#include "MESA/MESA_prof_load.h"
+#include "Maat_rule.h"
+#include "Maat_command.h"
#define MGW_STRING_MAX 2048
#define MGW_PATH_MAX 256
#define MGW_SYMBOL_MAX 64
#define MGW_THREAD_MAX 128
-
-
+#define MGW_PACKET_MAX 3000
+#define HTABLE_QUERY_CB_SUCCESS 0
+#define HTABLE_QUERY_CB_FAILURE -1
+#define HTABLE_KEY_EXISTED 0
+#define HTABLE_KEY_NOT_EXISTED -1
+#define PROTO_TCP 0x06
+#define PROTO_UDP 0x11
+#define PROTO_ICMP 0x01
#define likely(expr) __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)
@@ -24,3 +40,19 @@ do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
#define MGW_LOG_DEBUG(handler, fmt, ...) \
do { MESA_handle_runtime_log(handler, RLOG_LV_DEBUG, "mgw", fmt, ##__VA_ARGS__); } while(0)
+struct htable_opts
+{
+ int mho_screen_print_ctrl;
+ int mho_thread_safe;
+ int mho_mutex_num;
+ int mho_hash_slot_size;
+ int mho_expire_time;
+ void *logger;
+};
+
+MESA_htable_handle mgw_utils_create_htable(const char *symbol, struct htable_opts *_htable_opts, void *free_data_cb, void *expire_notify_cb);
+
+
+unsigned int mgw_utils_get_random(unsigned int num);
+
+const char * mgw_utils_inet_ntoa(unsigned int ip); \ No newline at end of file
diff --git a/common/src/mgw_socket.cpp b/common/src/mgw_socket.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/src/mgw_socket.cpp
diff --git a/common/src/mgw_tun.cpp b/common/src/mgw_tun.cpp
new file mode 100644
index 0000000..c57c12f
--- /dev/null
+++ b/common/src/mgw_tun.cpp
@@ -0,0 +1,108 @@
+#pragma once
+
+#ifndef TUN_H_INCLUDED
+#define TUN_H_INCLUDED
+#endif
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <linux/if_ether.h>
+#include <stddef.h>
+#include <net/if.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <linux/if_tun.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+
+#include "mgw_utils.h"
+#include "mgw_tun.h"
+
+struct mgw_tun_handle
+{
+ void* logger;
+ int fd;
+};
+
+
+struct mgw_tun_handle * mgw_tun_init(char *dev, void *logger)
+{
+ struct ifreq ifr;
+ int fd, err;
+ if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+ {
+ MGW_LOG_ERROR(logger, "Failed at open /dev/net/tun: errno %d is %s", errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TUN | IFF_NO_PI;//不包含tun包信息
+ if (*dev)
+ {
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+ if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
+ {
+ MGW_LOG_ERROR(logger, "Failed at ioctl: errno %d is %s", errno,strerror(errno));
+ close(fd);
+ exit(EXIT_FAILURE);
+ }
+ strcpy(dev, ifr.ifr_name);
+ struct mgw_tun_handle *handle = ALLOC(struct mgw_tun_handle, 1);
+ handle->fd = fd;
+ handle->logger = logger;
+ return handle;
+}
+
+void mgw_tun_destroy(struct mgw_tun_handle *handle)
+{
+ close(handle->fd);
+ FREE(&handle);
+}
+
+
+int mgw_tun_read(struct mgw_tun_handle *handle, char *recv_ip_pkts, size_t ip_pkt_len)
+ {
+ int recv_ip_len = 0;
+ recv_ip_len = read(handle->fd, recv_ip_pkts, ip_pkt_len);
+ if(recv_ip_len < 0)
+ {
+ close(handle->fd);
+ MGW_LOG_ERROR(handle->logger, "Failed at tun_read errno %d is %s\n", errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ else
+ {
+ return recv_ip_len;
+ }
+ }
+
+
+ /**************************************************************************
+ * write_to_tun: write data to tun *
+ * return:write bytes *
+ **************************************************************************/
+int mgw_tun_write(int tun_fd, char *send_ip_pkts, int send_ip_len)
+ {
+ assert(send_ip_pkts !=NULL);
+ assert(send_ip_len > 0);
+ int cur_snd_ip_len = 0 ;
+ cur_snd_ip_len = write(tun_fd, send_ip_pkts, send_ip_len);
+ if(cur_snd_ip_len < 0)
+ {
+ printf(" send ip pkts errno = %d, content is %s\n",errno, strerror(errno));
+ assert(0);
+ }
+ else
+ {
+ if(cur_snd_ip_len < send_ip_len)
+ {
+ close(tun_fd);
+ printf("the ip data can not send completely!\n");
+ assert(0);
+ }
+ else
+ {
+ return cur_snd_ip_len;
+ }
+ }
+ }
diff --git a/common/src/mgw_utils.cpp b/common/src/mgw_utils.cpp
index e69de29..68fa1f8 100644
--- a/common/src/mgw_utils.cpp
+++ b/common/src/mgw_utils.cpp
@@ -0,0 +1,62 @@
+#include "mgw_utils.h"
+
+static int __wrapper_MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, unsigned value, void *logger, const char *symbol)
+{
+ int ret = MESA_htable_set_opt(table, opt_type, &value, (int)(sizeof(value)));
+ if(unlikely(ret != 0))
+ {
+ exit(EXIT_FAILURE);
+ MGW_LOG_ERROR(logger, "Failed at MESA_htable_set_opt, htable is %s, opt_type is %d", symbol, opt_type);
+ }
+ return ret;
+}
+
+static int __wrapper_MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, void * val, size_t len, void *logger, const char *symbol)
+{
+ int ret = MESA_htable_set_opt(table, opt_type, val, (int)len);
+ if(unlikely(ret != 0))
+ {
+ exit(EXIT_FAILURE);
+ MGW_LOG_ERROR(logger, "Failed at MESA_htable_set_opt, htable is %s, opt_type is %d", symbol, opt_type);
+ }
+ return ret;
+}
+
+MESA_htable_handle mgw_utils_create_htable(const char *symbol, struct htable_opts *_htable_opts, void *free_data_cb, void *expire_notify_cb)
+{
+ int ret = 0;
+ unsigned max_num = _htable_opts->mho_hash_slot_size * 4;
+ void *logger = _htable_opts->logger;
+ MESA_htable_handle htable = MESA_htable_born();
+ __wrapper_MESA_htable_set_opt(htable, MHO_SCREEN_PRINT_CTRL, _htable_opts->mho_screen_print_ctrl, logger, symbol);
+ __wrapper_MESA_htable_set_opt(htable, MHO_THREAD_SAFE, _htable_opts->mho_thread_safe, logger, symbol);
+ __wrapper_MESA_htable_set_opt(htable, MHO_MUTEX_NUM, _htable_opts->mho_mutex_num, logger, symbol);
+ __wrapper_MESA_htable_set_opt(htable, MHO_HASH_SLOT_SIZE, _htable_opts->mho_hash_slot_size, logger, symbol);
+ __wrapper_MESA_htable_set_opt(htable, MHO_HASH_MAX_ELEMENT_NUM, _htable_opts->mho_hash_slot_size * 4, logger, symbol);
+ __wrapper_MESA_htable_set_opt(htable, MHO_EXPIRE_TIME, _htable_opts->mho_expire_time, logger, symbol);
+ __wrapper_MESA_htable_set_opt(htable, MHO_ELIMIMINATE_TYPE, HASH_ELIMINATE_ALGO_FIFO, logger, symbol);
+ ret = __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_FREE,
+ (void *)free_data_cb, sizeof(free_data_cb), logger, symbol);
+ //ret = __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_EXPIRE_NOTIFY,
+ // (void *)key_keeper_verify_cb);
+ ret = MESA_htable_mature(htable);
+ if(unlikely(ret != 0))
+ {
+ exit(EXIT_FAILURE);
+ MGW_LOG_ERROR(logger, "Failed at MESA_htable_mature, htable is %s", symbol);
+ }
+ return htable;
+}
+
+
+unsigned int mgw_utils_get_random(unsigned int num)
+{
+ srand((unsigned)time(NULL));
+ return (rand() % num);
+}
+
+const char * mgw_utils_inet_ntoa(unsigned int ip)
+ {
+ const char *_ip = inet_ntoa(*(struct in_addr *)&ip);
+ return _ip;
+ } \ No newline at end of file
diff --git a/conf/mgw.conf b/conf/mgw.conf
new file mode 100644
index 0000000..cfd337d
--- /dev/null
+++ b/conf/mgw.conf
@@ -0,0 +1,23 @@
+[global]
+log_path = ./log/mgw.log
+
+[maat]
+table_info_path = ./conf/table_info.conf
+max_thread_num = 1
+maat_redis_ip = 127.0.0.1
+maat_redis_port = 6379
+stat_file_path = ./log/maat_stat.log
+
+
+[htable_opt]
+mho_screen_print_ctrl = 0
+mho_thread_safe = 1
+mho_mutex_num = 16
+mho_hash_slot_size = 16
+mho_expire_time = -1
+
+[vpn_server]
+vpn_server_ip = localhost
+vpn_server_prot = 443
+vpn_server_passwd = 111111
+hub_list = {NewHub0|111111},{NewHub1|111111}
diff --git a/conf/table_info.conf b/conf/table_info.conf
new file mode 100644
index 0000000..7192d09
--- /dev/null
+++ b/conf/table_info.conf
@@ -0,0 +1,18 @@
+#each collumn seperate with '\t'
+#id (0~65535)
+#name string
+#type one of ip,expr,expr_plus,digest,intval,compile or plugin
+#src_charset one of GBK,BIG5,UNICODE,UTF8
+#dst_charset combined by GBK,BIG5,UNICODE,UTF8,seperate with '/'
+#do_merege [yes/no]
+#cross cache [number]
+#quick mode [quickon/quickoff], default [quickoff]
+#For ip/intval/digest/compile/group table.
+#id name type
+#
+#For plugin table. The first column's id is 1. 0 as not speicified.
+#id name type column_define
+#
+#For expr/expr_plus Table
+#id name type src_charset dst_charset do_merge cross_cache quick_mode
+0 QD_ENTRY_INFO plugin 4 --