diff options
| author | 崔一鸣 <[email protected]> | 2018-11-13 21:49:32 +0800 |
|---|---|---|
| committer | 崔一鸣 <[email protected]> | 2018-11-13 21:49:32 +0800 |
| commit | de5be3b41f49183163a6576728b9578ad81d8d66 (patch) | |
| tree | 6bda75e2699f2f699801ab178866239d282e6b5a | |
| parent | 5beded2ed4be958e035061024271cbd4513abb1f (diff) | |
增加nat模块,ip管理模块
| -rw-r--r-- | .vscode/ftp-kr.json | 2 | ||||
| -rw-r--r-- | .vscode/ftp-kr.sync.cache.json | 174 | ||||
| -rw-r--r-- | access/CMakeLists.txt | 29 | ||||
| -rw-r--r-- | access/include/ip_mgr.h | 13 | ||||
| -rw-r--r-- | access/include/nat.h | 8 | ||||
| -rw-r--r-- | access/include/tun.h | 20 | ||||
| -rw-r--r-- | access/include/vpn_monitor.h | 10 | ||||
| -rw-r--r-- | access/src/ip_mgr.cpp | 374 | ||||
| -rw-r--r-- | access/src/main.cpp | 156 | ||||
| -rw-r--r-- | access/src/nat.cpp | 384 | ||||
| -rw-r--r-- | access/src/vpn_monitor.cpp | 253 | ||||
| -rw-r--r-- | access/test/test_MESA_htable.cpp | 47 | ||||
| -rw-r--r-- | access/test/test_maat_redis.cpp | 10 | ||||
| -rw-r--r-- | access/test/test_tun.cpp (renamed from access/src/tun.cpp) | 211 | ||||
| -rw-r--r-- | common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | common/include/mgw_socket.h | 0 | ||||
| -rw-r--r-- | common/include/mgw_tun.h | 11 | ||||
| -rw-r--r-- | common/include/mgw_utils.h | 38 | ||||
| -rw-r--r-- | common/src/mgw_socket.cpp | 0 | ||||
| -rw-r--r-- | common/src/mgw_tun.cpp | 108 | ||||
| -rw-r--r-- | common/src/mgw_utils.cpp | 62 | ||||
| -rw-r--r-- | conf/mgw.conf | 23 | ||||
| -rw-r--r-- | conf/table_info.conf | 18 |
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 -- |
