diff options
| author | 崔一鸣 <[email protected]> | 2018-12-13 19:55:59 +0800 |
|---|---|---|
| committer | 崔一鸣 <[email protected]> | 2018-12-13 19:55:59 +0800 |
| commit | 608aea42336fcc768e3eecaa12c846266d4bcd69 (patch) | |
| tree | 495fafa70961d4c1389f73d5d78e6212a227900b | |
| parent | 250f47e34d2d30e099d167cc8eb979eff13d8dd4 (diff) | |
增加dnat模块
| -rw-r--r-- | .vscode/ftp-kr.sync.cache.json | 33 | ||||
| -rw-r--r-- | access/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | access/include/dnat.h | 9 | ||||
| -rw-r--r-- | access/include/ip_mgr.h | 39 | ||||
| -rw-r--r-- | access/include/nat.h | 9 | ||||
| -rw-r--r-- | access/include/snat.h | 10 | ||||
| -rw-r--r-- | access/include/udp_server.h | 3 | ||||
| -rw-r--r-- | access/src/dnat.cpp | 251 | ||||
| -rw-r--r-- | access/src/ip_mgr.cpp | 789 | ||||
| -rw-r--r-- | access/src/main.cpp | 333 | ||||
| -rw-r--r-- | access/src/nat.cpp | 574 | ||||
| -rw-r--r-- | access/src/snat.cpp | 339 | ||||
| -rw-r--r-- | access/src/udp_server.cpp | 48 | ||||
| -rw-r--r-- | access/src/vpn_monitor.cpp | 7 | ||||
| -rw-r--r-- | common/include/mgw_utils.h | 63 | ||||
| -rw-r--r-- | common/src/mgw_tun.cpp | 14 | ||||
| -rw-r--r-- | common/src/mgw_utils.cpp | 112 | ||||
| -rw-r--r-- | conf/mgw.conf | 62 | ||||
| -rw-r--r-- | conf/table_info.conf | 5 |
19 files changed, 1623 insertions, 1079 deletions
diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index 3b7d11d..45eb287 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -25,7 +25,7 @@ "mgw.conf": { "type": "-", "size": 1869, - "lmtime": 1544358511216, + "lmtime": 1544440700496, "modified": false }, ".mgw.conf.swp": { @@ -70,7 +70,7 @@ "vpn_monitor.cpp": { "type": "-", "size": 9247, - "lmtime": 1544360519242, + "lmtime": 1544438911926, "modified": false }, "udp_server.cpp": { @@ -278,14 +278,14 @@ "systemd": { "mgw.service": { "type": "-", - "size": 135, - "lmtime": 1544360675019, + "size": 171, + "lmtime": 1544421988405, "modified": false }, "mgw.sh": { "type": "-", - "size": 2638, - "lmtime": 1544360675020, + "size": 2633, + "lmtime": 1544422547180, "modified": false }, ".mgw.service.swp": { @@ -306,6 +306,27 @@ "lmtime": 1544360705622, "modified": false } + }, + "rpm_build": { + "build_rpm.sh": { + "type": "-", + "size": 826, + "lmtime": 1544420024859, + "modified": false + }, + "mgw.spec": { + "type": "-", + "size": 781, + "lmtime": 1544421599722, + "modified": false + }, + "mgw-1.0.1.tar.gz": { + "type": "-", + "size": 1943051, + "lmtime": 0, + "modified": false + }, + "RPMS": {} } } } diff --git a/access/CMakeLists.txt b/access/CMakeLists.txt index 92523a0..9c99f82 100644 --- a/access/CMakeLists.txt +++ b/access/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(mgw src/main.cpp src/vpn_monitor.cpp src/nat.cpp src/ip_mgr.cpp src/udp_server.cpp) +add_executable(mgw src/main.cpp src/vpn_monitor.cpp src/snat.cpp src/dnat.cpp src/ip_mgr.cpp src/udp_server.cpp) target_include_directories(mgw PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) diff --git a/access/include/dnat.h b/access/include/dnat.h new file mode 100644 index 0000000..143da80 --- /dev/null +++ b/access/include/dnat.h @@ -0,0 +1,9 @@ +struct dnat_handle; + +struct dnat_handle * dnat_init(const char *profile, struct ip_mgr_handle *_ip_mgr_handle, struct field_stat_handle *fs_handle, void *logger); + +void dnat_destroy(struct dnat_handle *handle); + +int dnat_tx_convert(struct dnat_handle *handle, char *buff, int len, uint32_t *mrl_ip); + +int dnat_rx_convert(struct dnat_handle *handle, char *buff, int len);
\ No newline at end of file diff --git a/access/include/ip_mgr.h b/access/include/ip_mgr.h index 9b8c2a7..41f09f9 100644 --- a/access/include/ip_mgr.h +++ b/access/include/ip_mgr.h @@ -1,34 +1,13 @@ -#define IP_MGR_MAC_LEN 18 -#define IP_MGR_IP_LEN 16 -#define IP_MGR_PORT_LEN 6 - -struct ip_mgr_cand_ip_detail -{ - uint32_t ip; - int reference; - struct ip_mgr_vxlan_info *vxlan_info; - uint32_t mrl_ip; -}; +struct ip_mgr_handle; -struct ip_mgr_vxlan_info -{ - int vxlan_link_id; - int vxlan_encap_type; - int vxlan_link_dir; - int vxlan_vpn_id; - char vxlan_outer_local_port[IP_MGR_PORT_LEN]; - char vxlan_outer_gdev_port[IP_MGR_PORT_LEN]; - char vxlan_outer_local_ip[IP_MGR_IP_LEN]; - char vxlan_outer_gdev_ip[IP_MGR_IP_LEN];//串行设备IP - char vxlan_outer_local_mac[IP_MGR_MAC_LEN];//接收到的数据包的本地设备MAC地址 - char vxlan_outer_gdev_mac[IP_MGR_MAC_LEN];//接收到的数据包的串行设备MAC地址 - char vxlan_inner_smac[IP_MGR_MAC_LEN]; - char vxlan_inner_dmac[IP_MGR_MAC_LEN]; -}; +struct ip_mgr_handle *ip_mgr_init(const char *profile, struct field_stat_handle *fs_handle, void *logger); -struct ip_mgr_handle; -struct ip_mgr_handle *ip_mgr_init(const char *profile, MESA_htable_handle cand_ip_detail_htable, struct field_stat_handle *fs_handle, - Maat_feather_t Maat_feather_cand, Maat_feather_t Maat_feather_policy, void *logger); void ip_mgr_destroy(struct ip_mgr_handle *handle); -int ip_mgr_candidata_ip_get(struct ip_mgr_handle *handle, const char *user_name, uint32_t *selected_ip);
\ No newline at end of file + +int ip_mgr_dnat_policy_query(struct ip_mgr_handle *handle, uint32_t orig_ip, + uint16_t orig_port, uint32_t *trans_ip, uint16_t *trans_port); + +int ip_mgr_mrl_ip_query(struct ip_mgr_handle *handle, uint32_t back_ip, uint32_t *mrl_ip); + +int ip_mgr_snat_cand_ip_get(struct ip_mgr_handle *handle, const char *user_name, uint32_t *selected_ip);
\ No newline at end of file diff --git a/access/include/nat.h b/access/include/nat.h deleted file mode 100644 index 5df0104..0000000 --- a/access/include/nat.h +++ /dev/null @@ -1,9 +0,0 @@ -#define NAT_COVERT_SUCCESS -1 -#define NAT_COVERT_FAILURE 0 - -struct nat_handle; -struct nat_handle * nat_init(const char *profile, MESA_htable_handle ip2user_htable, MESA_htable_handle cand_ip_detail_htable, - struct field_stat_handle *fs_handle, void *logger); -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, struct ip_mgr_vxlan_info **vxlan_info, uint32_t *mrl_ip); -int nat_dest_convert(struct nat_handle *handle, char *buff, int len);
\ No newline at end of file diff --git a/access/include/snat.h b/access/include/snat.h new file mode 100644 index 0000000..a77915d --- /dev/null +++ b/access/include/snat.h @@ -0,0 +1,10 @@ +struct snat_handle; + +struct snat_handle * snat_init(const char *profile, MESA_htable_handle ip2user_htable, struct ip_mgr_handle *_ip_mgr_handle, + struct field_stat_handle *fs_handle, void *logger); + +void snat_destroy(struct snat_handle *handle); + +int snat_tx_convert(struct snat_handle *handle, char *buff, int len, uint32_t *mrl_ip); + +int snat_rx_convert(struct snat_handle *handle, char *buff, int len);
\ No newline at end of file diff --git a/access/include/udp_server.h b/access/include/udp_server.h index a326327..40917a2 100644 --- a/access/include/udp_server.h +++ b/access/include/udp_server.h @@ -2,7 +2,8 @@ struct udp_server_args { void *logger; const char *profile; - struct nat_handle *_nat_handle; + struct snat_handle *_snat_handle; + struct dnat_handle *_dnat_handle; struct mgw_tun_handle *tun_handle; struct field_stat_handle *fs_handle; }; diff --git a/access/src/dnat.cpp b/access/src/dnat.cpp new file mode 100644 index 0000000..d511b2f --- /dev/null +++ b/access/src/dnat.cpp @@ -0,0 +1,251 @@ +#include "mgw_utils.h" +#include "dnat.h" +#include "ip_mgr.h" + +struct dnat_handle +{ + void *logger; + struct ip_mgr_handle *_ip_mgr_handle; + MESA_htable_handle dnat_rx_htable; + MESA_htable_handle dnat_tx_htable; +}; + + +struct dnat_tx_htable_value +{ + struct mgw_utils_sess sess; + uint32_t mrl_ip; +}; + +static struct field_stat_handle *g_fs_handle = NULL; + +static void dnat_rx_htable_data_free_cb(void *data) +{ + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); + FREE(&data); +} + +static void dnat_tx_htable_data_free_cb(void *data) +{ + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_tx, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); + FREE(&data); +} + + +struct dnat_handle * dnat_init(const char *profile, struct ip_mgr_handle *_ip_mgr_handle, struct field_stat_handle *fs_handle, void *logger) +{ + struct dnat_handle *handle = ALLOC(struct dnat_handle, 1); + handle->logger = logger; + handle->_ip_mgr_handle = _ip_mgr_handle; + handle->dnat_rx_htable = mgw_utils_create_htable(profile, "dnat_rx_htable", (void *)dnat_rx_htable_data_free_cb, NULL, logger); + handle->dnat_tx_htable = mgw_utils_create_htable(profile, "dnat_tx_htable", (void *)dnat_tx_htable_data_free_cb, NULL, logger); + g_fs_handle = fs_handle; + return handle; +} + +void dnat_destroy(struct dnat_handle *handle) +{ + MESA_htable_destroy(handle->dnat_rx_htable, NULL); + MESA_htable_destroy(handle->dnat_tx_htable, NULL); + FREE(&handle); +} + +static long dnat_rx_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg) +{ + struct mgw_utils_sess *dup_value = (struct mgw_utils_sess *)user_arg; + if(data != NULL) + { + struct mgw_utils_sess *_data = (struct mgw_utils_sess *)data; + dup_value->proto = _data->proto; + dup_value->sip = _data->sip; + dup_value->sport = _data->sport; + dup_value->dip = _data->dip; + dup_value->dport = _data->dport; + return MGW_HTABLE_KEY_EXISTED; + } + else + { + return MGW_HTABLE_KEY_NOT_EXISTED; + } +} + +static long dnat_tx_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg) +{ + struct dnat_tx_htable_value *dup_value = (struct dnat_tx_htable_value *)user_arg; + if(data != NULL) + { + struct dnat_tx_htable_value *_data = (struct dnat_tx_htable_value *)data; + dup_value->sess.proto = _data->sess.proto; + dup_value->sess.sip = _data->sess.sip; + dup_value->sess.sport = _data->sess.sport; + dup_value->sess.dip = _data->sess.dip; + dup_value->sess.dport = _data->sess.dport; + dup_value->mrl_ip = _data->mrl_ip; + return MGW_HTABLE_KEY_EXISTED; + } + else + { + return MGW_HTABLE_KEY_NOT_EXISTED; + } +} + + +int dnat_tx_convert(struct dnat_handle *handle, char *buff, int len, uint32_t *mrl_ip) +{ + void *logger = handle->logger; + //get session + struct mgw_utils_sess *dnat_tx_key = ALLOC(struct mgw_utils_sess, 1); + int rtn = mgw_utils_pkt_sess_parse(buff, len, dnat_tx_key); + if(rtn == -1) + { + FREE(&dnat_tx_key); + MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len); + return MGW_DROP; + } + char dnat_tx_key_str[MGW_SYMBOL_MAX]; + char dnat_tx_value_str[MGW_SYMBOL_MAX]; + mgw_utils_sess_to_str(dnat_tx_key, dnat_tx_key_str); + //query dnat_tx_htable + long cb_rtn = -1; + struct dnat_tx_htable_value dnat_tx_dup_value; + MESA_htable_search_cb(handle->dnat_tx_htable, (const unsigned char *)(dnat_tx_key), sizeof(struct mgw_utils_sess), dnat_tx_htable_query_cb, + (void *)(&dnat_tx_dup_value), &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_tx, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + FREE(&dnat_tx_key); + if(cb_rtn == MGW_HTABLE_KEY_EXISTED) + { + //replace + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_tx, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + mgw_utils_pkt_sess_replace(buff, len, &(dnat_tx_dup_value.sess)); + *mrl_ip = dnat_tx_dup_value.mrl_ip; + mgw_utils_sess_to_str(&(dnat_tx_dup_value.sess), dnat_tx_value_str); + MGW_LOG_INFO(logger, "Succeed at dnat_rx_convert: %s ---> %s", dnat_tx_key_str, dnat_tx_value_str); + return MGW_FORWORD; + } + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_tx, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + return MGW_BYPASS; +} + +int dnat_rx_convert(struct dnat_handle *handle, char *buff, int len) +{ + void *logger = handle->logger; + //get session + struct mgw_utils_sess *dnat_rx_key = ALLOC(struct mgw_utils_sess, 1); + int rtn = mgw_utils_pkt_sess_parse(buff, len, dnat_rx_key); + if(rtn == -1) + { + FREE(&dnat_rx_key); + MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len); + return MGW_DROP; + } + char dnat_rx_key_str[MGW_SYMBOL_MAX]; + char dnat_rx_value_str[MGW_SYMBOL_MAX]; + char dnat_tx_key_str[MGW_SYMBOL_MAX]; + char dnat_tx_value_str[MGW_SYMBOL_MAX]; + mgw_utils_sess_to_str(dnat_rx_key, dnat_rx_key_str); + //query dnat_rx_htable + long cb_rtn = -1; + struct mgw_utils_sess dnat_rx_dup_value; + MESA_htable_search_cb(handle->dnat_rx_htable, (const unsigned char *)(dnat_rx_key), sizeof(struct mgw_utils_sess), dnat_rx_htable_query_cb, + (void *)(&dnat_rx_dup_value), &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_EXISTED) + { + //replace + FREE(&dnat_rx_key); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + mgw_utils_pkt_sess_replace(buff, len, &dnat_rx_dup_value); + mgw_utils_sess_to_str(&dnat_rx_dup_value, dnat_rx_value_str); + MGW_LOG_INFO(logger, "Succeed at dnat_rx_convert: %s ---> %s", dnat_rx_key_str, dnat_rx_value_str); + return MGW_FORWORD; + } + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + uint32_t trans_ip; + uint16_t trans_port; + char orig_ip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(dnat_rx_key->dip, orig_ip_str); + //query dnat_policy + rtn = ip_mgr_dnat_policy_query(handle->_ip_mgr_handle, dnat_rx_key->dip, dnat_rx_key->dport, &trans_ip, &trans_port); + if(rtn < 0) + { + FREE(&dnat_rx_key); + MGW_LOG_ERROR(logger, "Failed at dnat_rx_convert: policy not found, original dest is <%s, %d>", orig_ip_str, ntohs(dnat_rx_key->dport)); + return MGW_DROP; + } + //query mrl_ip + uint32_t mrl_ip; + rtn = ip_mgr_mrl_ip_query(handle->_ip_mgr_handle, dnat_rx_key->dip, &mrl_ip); + if(rtn < 0) + { + FREE(&dnat_rx_key); + MGW_LOG_ERROR(logger, "Failed at dnat_rx_convert: mrl_ip not found, original dest is <%s, %d>", orig_ip_str, ntohs(dnat_rx_key->dport)); + return MGW_DROP; + } + //add to dnat_rx_table + struct mgw_utils_sess *dnat_rx_value = ALLOC(struct mgw_utils_sess, 1); + dnat_rx_value->sip = dnat_rx_key->sip; + dnat_rx_value->sport = dnat_rx_key->sport; + dnat_rx_value->proto = dnat_rx_key->proto; + dnat_rx_value->dip = trans_ip; + dnat_rx_value->dport = trans_port; + mgw_utils_sess_to_str(dnat_rx_value, dnat_rx_value_str); + rtn = MESA_htable_add(handle->dnat_rx_htable, (const unsigned char *)(dnat_rx_key), sizeof(struct mgw_utils_sess), (const void*)dnat_rx_value); + if(rtn < 0) + { + FREE(&dnat_rx_value); + FREE(&dnat_rx_key); + MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, key is %s, value is %s, rtn is %d", + "dnat_rx_htable", dnat_rx_key_str, dnat_rx_value_str, rtn); + return MGW_DROP; + } + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); + MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, key is %s, value is %s", + "dnat_rx_htable", dnat_rx_key_str, dnat_rx_value_str); + //add to dnat_tx_table + struct mgw_utils_sess *dnat_tx_key = ALLOC(struct mgw_utils_sess, 1); + dnat_tx_key->sip = dnat_rx_value->dip; + dnat_tx_key->sport = dnat_rx_value->dport; + dnat_tx_key->proto = dnat_rx_value->proto; + dnat_tx_key->dip = dnat_rx_value->sip; + dnat_tx_key->dport = dnat_rx_value->dport; + struct dnat_tx_htable_value *dnat_tx_value = ALLOC(struct dnat_tx_htable_value, 1); + dnat_tx_value->sess.sip = dnat_rx_key->dip; + dnat_tx_value->sess.sport = dnat_rx_key->dport; + dnat_tx_value->sess.proto = dnat_rx_key->proto; + dnat_tx_value->sess.dip = dnat_rx_key->sip; + dnat_tx_value->sess.dport = dnat_rx_key->sport; + dnat_tx_value->mrl_ip = mrl_ip; + mgw_utils_sess_to_str(dnat_tx_key, dnat_tx_key_str); + mgw_utils_sess_to_str(&(dnat_tx_value->sess), dnat_tx_value_str); + rtn = MESA_htable_add(handle->dnat_tx_htable, (const unsigned char *)(dnat_tx_key), sizeof(struct mgw_utils_sess), (const void*)dnat_tx_value); + if(rtn < 0) + { + MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, key is %s, value is %s, rtn is %d", + "dnat_tx_htable", dnat_tx_key_str, dnat_tx_value_str, rtn); + //dnat_tx_table and dnat_rx_table are Transaction + rtn = MESA_htable_del(handle->dnat_rx_htable, (const unsigned char *)dnat_rx_key, sizeof(struct mgw_utils_sess), NULL); + if(rtn < 0) + { + MGW_LOG_ERROR(logger, "MESA_htable: Failed at del, table is %s, key is %s, value is %s, rtn is %s", + "dnat_rx_htable", dnat_rx_key_str, dnat_rx_value_str, rtn); + } + else + { + MGW_LOG_INFO(logger, "MESA_htable: Succeed at del, table is %s, key is %s, value is %s", + "dnat_rx_htable", dnat_rx_key_str, dnat_rx_value_str); + } + FREE(&dnat_rx_key); + FREE(&dnat_tx_key); + FREE(&dnat_tx_value); + return MGW_DROP; + } + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_tx, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); + MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, key is %s, value is %s", + "dnat_tx_htable", dnat_tx_key_str, dnat_tx_value_str); + //replace + FREE(&dnat_rx_key); + FREE(&dnat_tx_key); + mgw_utils_pkt_sess_replace(buff, len, dnat_rx_value); + MGW_LOG_INFO(logger, "Succeed at dnat_rx_convert: %s ---> %s", dnat_rx_key_str, dnat_rx_value_str); + return MGW_FORWORD; +}
\ No newline at end of file diff --git a/access/src/ip_mgr.cpp b/access/src/ip_mgr.cpp index 0203803..980eb78 100644 --- a/access/src/ip_mgr.cpp +++ b/access/src/ip_mgr.cpp @@ -2,139 +2,289 @@ #include "mgw_utils.h" #include "ip_mgr.h" -#define GROUP_IP_MAX 4096 +#define SNAT_CAND_IP_GROUP_MAX 4096 + +static struct field_stat_handle *g_fs_handle = NULL; struct ip_mgr_handle { void *logger; - Maat_feather_t Maat_feather_cand; - Maat_feather_t Maat_feather_policy; - MESA_htable_handle user_policy_htable; //expire_time: 0 - MESA_htable_handle cand_ip_group_htable; //expire_time: 0 - MESA_htable_handle cand_ip_detail_htable; //expire_time: 0 - struct field_stat_handle *fs_handle; + Maat_feather_t Maat_feather_snat_policy; + Maat_feather_t Maat_feather_dnat_policy; + Maat_feather_t Maat_feather_snat_cand_ip; + Maat_feather_t Maat_feather_mrl_ip; + MESA_htable_handle snat_policy_htable; //expire_time: 0 + MESA_htable_handle dnat_policy_htable; //expire_time: 0 + MESA_htable_handle snat_cand_ip_htable; //expire_time: 0 + MESA_htable_handle mrl_ip_htable; //expire_time: 0 }; -struct user_policy_htable_value +struct snat_policy_htable_value { char user_name[MGW_SYMBOL_MAX]; int group_id; }; -struct cand_ip_group_htable_value +struct dnat_policy_htable_key +{ + uint32_t orig_ip; + uint16_t orig_port; +}; + +struct dnat_policy_htable_value { - uint32_t ip_list[GROUP_IP_MAX]; + uint32_t trans_ip; + uint16_t trans_port; +}; + +struct mrl_ip_htable_value +{ + uint32_t back_ip; + uint32_t mrl_ip; +}; + +struct snat_cand_ip_detail +{ + uint32_t ip; + int group_id; + int addr_type; + int location; + int reference; +}; + +struct snat_cand_ip_group +{ + struct snat_cand_ip_detail *ip_list[SNAT_CAND_IP_GROUP_MAX]; unsigned int num; }; -static long user_policy_htable_query_cb(void *data, const uchar *key, uint size, void *user_args) +struct snat_cand_ip_query_cb_get_args { - struct user_policy_htable_value *value = (struct user_policy_htable_value *)data; - int *group_id = (int *)user_args; + struct ip_mgr_handle *handle; + int group_id; + uint32_t *ip; + bool existed; +}; + +struct snat_cand_ip_query_cb_add_args +{ + struct ip_mgr_handle *handle; + int group_id; + struct snat_cand_ip_detail ip_detail; +}; + +struct snat_cand_ip_query_cb_del_args +{ + struct ip_mgr_handle *handle; + int group_id; + uint32_t ip; +}; + +static long snat_policy_query_cb(void *data, const uchar *key, uint size, void *user_args) +{ + struct snat_policy_htable_value *dup_value = (struct snat_policy_htable_value *)user_args; if(data != NULL) { - *group_id = value->group_id; - return HTABLE_KEY_EXISTED; + struct snat_policy_htable_value *_data = (struct snat_policy_htable_value *)data; + strncpy(dup_value->user_name, _data->user_name, MGW_SYMBOL_MAX); + dup_value->group_id = _data->group_id; + return MGW_HTABLE_KEY_EXISTED; } - return HTABLE_KEY_NOT_EXISTED; + return MGW_HTABLE_KEY_NOT_EXISTED; } +static long dnat_policy_query_cb(void *data, const uchar *key, uint size, void *user_args) +{ + struct dnat_policy_htable_value *dup_value = (struct dnat_policy_htable_value *)user_args; + if(data != NULL) + { + struct dnat_policy_htable_value *_data = (struct dnat_policy_htable_value *)data; + dup_value->trans_ip = _data->trans_ip; + dup_value->trans_port = _data->trans_port; + return MGW_HTABLE_KEY_EXISTED; + } + return MGW_HTABLE_KEY_NOT_EXISTED; +} + +static long mrl_ip_query_cb(void *data, const uchar *key, uint size, void *user_args) +{ + struct mrl_ip_htable_value *dup_value = (struct mrl_ip_htable_value *)user_args; + if(data != NULL) + { + struct mrl_ip_htable_value *_data = (struct mrl_ip_htable_value *)data; + dup_value->back_ip = _data->back_ip; + dup_value->mrl_ip = _data->mrl_ip; + return MGW_HTABLE_KEY_EXISTED; + } + return MGW_HTABLE_KEY_NOT_EXISTED; +} + +int ip_mgr_dnat_policy_query(struct ip_mgr_handle *handle, uint32_t orig_ip, uint16_t orig_port, uint32_t *trans_ip, uint16_t *trans_port) +{ + void *logger = handle->logger; + long cb_rtn = -1; + struct dnat_policy_htable_key *key = ALLOC(struct dnat_policy_htable_key, 1); + key->orig_ip = orig_ip; + key->orig_port = orig_port; + char orig_ip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(orig_ip, orig_ip_str); + struct dnat_policy_htable_value dup_value; + MESA_htable_search_cb(handle->dnat_policy_htable, (const unsigned char *)key, sizeof(struct dnat_policy_htable_key), + dnat_policy_query_cb, &dup_value, &cb_rtn); + FREE(&key); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_policy, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_NOT_EXISTED) + { + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_policy, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + MGW_LOG_ERROR(logger, "MESA_htable: key not existed, table is %s, original dest is <%s:%d>", "dnat_policy_htable", orig_ip_str, ntohs(orig_port)); + return -1; + } + *trans_ip = dup_value.trans_ip; + *trans_port = dup_value.trans_port; + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_policy, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, original dest is <%s:%d>", "dnat_policy_htable", orig_ip_str, ntohs(orig_port)); + return 0; +} + +int ip_mgr_mrl_ip_query(struct ip_mgr_handle *handle, uint32_t back_ip, uint32_t *mrl_ip) +{ + void *logger = handle->logger; + long cb_rtn = -1; + char back_ip_str[MGW_SYMBOL_MAX]; + char mrl_ip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(back_ip, back_ip_str); + struct mrl_ip_htable_value dup_value; + MESA_htable_search_cb(handle->mrl_ip_htable, (const unsigned char *)(&back_ip), sizeof(uint32_t), + mrl_ip_query_cb, &dup_value, &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_mrl_ip, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_NOT_EXISTED) + { + FS_operate(g_fs_handle->handle, g_fs_handle->line_mrl_ip, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + MGW_LOG_ERROR(logger, "MESA_htable: key not existed, table is %s, back ip is %s", "mrl_ip_htable", back_ip_str); + return -1; + } + mgw_utils_inet_ntoa(dup_value.mrl_ip, mrl_ip_str); + *mrl_ip = dup_value.mrl_ip; + FS_operate(g_fs_handle->handle, g_fs_handle->line_mrl_ip, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, back ip is %s, mrl ip is %s", "mrl_ip_htable", back_ip_str, mrl_ip_str); + return 0; +} + +static long snat_cand_ip_query_cb_get(void *data, const uchar *key, uint size, void *user_args) +{ + struct snat_cand_ip_query_cb_get_args *args = (struct snat_cand_ip_query_cb_get_args *)user_args; + struct ip_mgr_handle *handle = args->handle; + void *logger = handle->logger; + int group_id = args->group_id; + if(data == NULL) + { + MGW_LOG_INFO(logger, "MESA_htable: key not existed, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + args->existed = false; + } + else + { + struct snat_cand_ip_group *ip_group = (struct snat_cand_ip_group *)data; + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + unsigned int num = ip_group->num; + if(num <= 0) + { + MGW_LOG_ERROR(logger, "group_id is %d, num of snat candidate ip is %d", group_id, num); + args->existed = false; + return MGW_HTABLE_QUERY_CB_SUCCESS; + } + unsigned int index = mgw_utils_get_random(num); + *(args->ip) = ip_group->ip_list[index]->ip; + args->existed = true; + return MGW_HTABLE_QUERY_CB_SUCCESS; + } + return MGW_HTABLE_QUERY_CB_SUCCESS; +} -int ip_mgr_candidata_ip_get(struct ip_mgr_handle *handle, const char *user_name, uint32_t *selected_ip) +int ip_mgr_snat_cand_ip_get(struct ip_mgr_handle *handle, const char *user_name, uint32_t *selected_ip) { - struct field_stat_handle *fs_handle = handle->fs_handle; void *logger = handle->logger; - long user_policy_cb_rtn = 0; + long 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); - FS_operate(fs_handle->handle, fs_handle->line_user_policy, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(user_policy_cb_rtn == HTABLE_KEY_EXISTED) + //query snat_policy + MESA_htable_search_cb(handle->snat_policy_htable, (const unsigned char *)user_name, key_size, + snat_policy_query_cb, &group_id, &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_policy, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_EXISTED) { - FS_operate(fs_handle->handle, fs_handle->line_user_policy, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - 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_group_htable_value *ip_group = NULL; - ip_group = (struct cand_ip_group_htable_value *)MESA_htable_search(handle->cand_ip_group_htable, (const unsigned char *)(&group_id), sizeof(group_id)); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(ip_group != NULL) + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_policy, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, user_name is %s, group id is %d", "snat_policy", user_name, group_id); + //query snat_cand_ip_htable + long cb_rtn = -1; + struct snat_cand_ip_query_cb_get_args args; + args.handle = handle; + args.ip = selected_ip; + MESA_htable_search_cb(handle->snat_cand_ip_htable, (const unsigned char *)(&group_id), sizeof(group_id), + snat_cand_ip_query_cb_get, &args, &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(args.existed) { - MGW_LOG_INFO(logger, "MESA_htable: key existed. table is %s, key is %d", "cand_ip_group_htable", group_id); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - 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 -1; - } - unsigned int index = mgw_utils_get_random(num); - *selected_ip = ip_group->ip_list[index]; return 0; } else { - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_ERROR(logger, "MESA_htable: key not existed. table is %s, key is %d", "cand_ip_group_htable", group_id); + MGW_LOG_ERROR(logger, "Failed at find available snat candidate ip, group id is %d", group_id); return -1; } } else { - FS_operate(fs_handle->handle, fs_handle->line_user_policy, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_ERROR(logger, "MESA_htable: key not existed. table is %s, key is %s", "user_policy_htable", user_name); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_policy, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + MGW_LOG_ERROR(logger, "MESA_htable: key not existed. table is %s, key is %s", "snat_policy_htable", user_name); return -1; } } -static void user_policy_htable_data_free_cb(void *data) +static void snat_policy_htable_data_free_cb(void *data) { FREE(&data); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_policy, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); } -static void cand_ip_group_htable_data_free_cb(void *data) +static void dnat_policy_htable_data_free_cb(void *data) { FREE(&data); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_policy, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); } - -static int delete_ip_from_group(uint32_t ip, struct cand_ip_group_htable_value *ip_group) +static void snat_cand_ip_htable_data_free_cb(void *data) { + struct snat_cand_ip_group *ip_group = (struct snat_cand_ip_group *)data; int num = ip_group->num; - int pos = -1; for(int i = 0; i < num; i++) { - if(ip_group->ip_list[i] == ip) - { - pos = i; - break; - } - } - if(pos == -1) - { - return -1; - } - for(int i = pos; i < num - 1; i++) - { - ip_group->ip_list[i] = ip_group->ip_list[i + 1]; + FREE(&(ip_group->ip_list[i])); } - ip_group->num --; - return 0; + FREE(&data); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); } +static void mrl_ip_htable_data_free_cb(void *data) +{ + FS_operate(g_fs_handle->handle, g_fs_handle->line_mrl_ip, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); + FREE(&data); +} -static void Maat_user_policy_start_cb(int update_type, void* args) +static void Maat_snat_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"); + MGW_LOG_INFO(logger, "Maat_redis: start callback, table is IP_SNAT_POLICY"); return; } -static void Maat_user_policy_update_cb(int table_id, const char* table_line, void* args) +static void Maat_snat_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; - struct field_stat_handle *fs_handle = handle->fs_handle; - MGW_LOG_INFO(logger, "Maat_redis: update callback, table is USER_POLICY_TABLE"); + MGW_LOG_INFO(logger, "Maat_redis: update callback, table is IP_SNAT_POLICY"); int config_id, group_id, is_valid; char user_type[MGW_SYMBOL_MAX]; char user_name[MGW_SYMBOL_MAX]; @@ -145,46 +295,46 @@ static void Maat_user_policy_update_cb(int table_id, const char* table_line, voi //printf("table line is %s\n", table_line); sscanf(table_line, "%d %d %s %s %s %d %d %d %d", &config_id, &group_id, user_type, user_name, translate_param, &do_log, &action, &service_id, &is_valid); //printf("user name is %s\n", user_name); - struct user_policy_htable_value *value = ALLOC(struct user_policy_htable_value, 1); + struct snat_policy_htable_value *value = ALLOC(struct snat_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); + //add snat_policy_htable + int rtn = MESA_htable_add(handle->snat_policy_htable, (const unsigned char *)user_name, key_size, value); if(rtn < 0 && rtn != MESA_HTABLE_RET_DUP_ITEM) { - MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at add, table is %s, user_name is %s, group_id is %d, rtn is %d", "user_policy_htable", user_name, group_id, rtn); + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at add, table is %s, user_name is %s, group_id is %d, rtn is %d", + "snat_policy_htable", user_name, group_id, rtn); return; } if(rtn >= 0) { - MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at add, table is %s, user_name is %s, group_id is %d", "user_policy_htable", user_name, group_id); - FS_operate(fs_handle->handle, fs_handle->line_user_policy, fs_handle->cloumn_element_num, FS_OP_ADD, 1); + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at add, table is %s, user_name is %s, group_id is %d", "snat_policy_htable", user_name, group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_policy, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); } } else { - //del user_policy_htable - int rtn = MESA_htable_del(handle->user_policy_htable, (const unsigned char *)user_name, key_size, NULL); + //del snat_policy_htable + int rtn = MESA_htable_del(handle->snat_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, rtn is %d", "user_policy_htable", user_name, group_id, rtn); + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at del, table is %s, user_name is %s, group_id is %d, rtn is %d", "snat_policy_htable", user_name, group_id, rtn); return; } - MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, user_name is %s, group_id is %d", "user_policy_htable", user_name, group_id); - FS_operate(fs_handle->handle, fs_handle->line_user_policy, fs_handle->cloumn_element_num, FS_OP_ADD, -1); + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, user_name is %s, group_id is %d", "snat_policy_htable", user_name, group_id); } return; } -static void Maat_user_policy_finish_cb(void* args) +static void Maat_snat_policy_finish_cb(void* args) { struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args; void *logger = handle->logger; - MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is USER_POLICY_TABLE"); + MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is snat_policy"); //Maat_feather_t feather = handle->feather; /* long long version=0; @@ -199,159 +349,316 @@ static void Maat_user_policy_finish_cb(void* args) return; } -static void Maat_cand_ip_start_cb(int update_type,void* args) +static void Maat_snat_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, updata_type is %d\n", update_type); + MGW_LOG_INFO(logger, "Maat_redis: start callback, table is IR_CANDIDATE_IP, updata_type is %d\n", update_type); return; } -static void Maat_cand_ip_update_cb(int table_id, const char* table_line, void* args) +static long snat_cand_ip_query_cb_add(void *data, const uchar *key, uint size, void *user_args) { - struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args; - struct field_stat_handle *fs_handle = handle->fs_handle; + struct snat_cand_ip_query_cb_add_args *args = (struct snat_cand_ip_query_cb_add_args *)user_args; + struct ip_mgr_handle *handle = args->handle; + int group_id = args->group_id; + struct snat_cand_ip_detail ip_detail = args->ip_detail; void *logger = handle->logger; - MGW_LOG_INFO(logger, "Maat_redis: update callback, table is CAND_IP_TABLE"); - //MGW_LOG_INFO(logger, "Maat_redis: update callback, table_line is %s", table_line); - int config_id, group_id, addr_type, location, link_id, encap_type, direction, is_valid, vpn_id; - char ip_addr[IP_MGR_IP_LEN]; - char mrl_ip[IP_MGR_IP_LEN]; - char outer_sport[IP_MGR_PORT_LEN]; - char outer_dport[IP_MGR_PORT_LEN]; - char outer_sip[IP_MGR_IP_LEN]; - char outer_dip[IP_MGR_IP_LEN]; - char outer_smac[IP_MGR_MAC_LEN]; - char outer_dmac[IP_MGR_MAC_LEN]; - char inner_smac[IP_MGR_MAC_LEN]; - char inner_dmac[IP_MGR_MAC_LEN]; - sscanf(table_line, "%d %d %d %s %d %s %d %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, &vpn_id, 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) + struct snat_cand_ip_group *ip_group = NULL; + if(data == NULL) { - //add cand_ip_group_htable - struct cand_ip_group_htable_value *ip_group = NULL; - ip_group = (struct cand_ip_group_htable_value *)MESA_htable_search(handle->cand_ip_group_htable, (const unsigned char *)(&group_id), sizeof(group_id)); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(ip_group == NULL) + MGW_LOG_INFO(logger, "MESA_htable: key not existed, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + ip_group = ALLOC(struct snat_cand_ip_group, 1); + ip_group->num = 0; + int rtn = MESA_htable_add(handle->snat_cand_ip_htable, (const unsigned char *)&group_id, sizeof(group_id), (void *)ip_group); + if(rtn < 0) { - MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, group_id is %d", "cand_ip_group_htable", group_id); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - ip_group = ALLOC(struct cand_ip_group_htable_value, 1); - ip_group->num = 0; - int rtn = MESA_htable_add(handle->cand_ip_group_htable, (const unsigned char *)&group_id, sizeof(group_id), (void *)ip_group); - if(rtn < 0) + FREE(&ip_group); + MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, group_id is %d, rtn is %d", "snat_cand_ip_htable", group_id, rtn); + MGW_LOG_ERROR(logger, "Failed at add ip to snat_cand_ip_group, group not existed, group_id is %d", group_id); + return MGW_HTABLE_QUERY_CB_SUCCESS; + } + MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); + } + else + { + ip_group = (struct snat_cand_ip_group *)data; + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + } + struct snat_cand_ip_detail *cand_ip_detail = ALLOC(struct snat_cand_ip_detail, 1); + cand_ip_detail->ip = ip_detail.ip; + cand_ip_detail->group_id = ip_detail.group_id; + cand_ip_detail->addr_type = ip_detail.addr_type; + cand_ip_detail->location = ip_detail.location; + int num = ip_group->num; + char ip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(ip_detail.ip, ip_str); + if(num >= SNAT_CAND_IP_GROUP_MAX) + { + FREE(&cand_ip_detail); + MGW_LOG_ERROR(logger, "Failed at add ip to snat_cand_ip_group, reach the max num %d of group, ip is %s, group_id is %d", + SNAT_CAND_IP_GROUP_MAX, ip_str, group_id); + return MGW_HTABLE_QUERY_CB_SUCCESS; + } + ip_group->ip_list[num] = cand_ip_detail; + ip_group->num++; + MGW_LOG_INFO(logger, "Succeed at add ip to snat_cand_ip_group, ip is %s, group_id is %d", ip_str, group_id); + return MGW_HTABLE_QUERY_CB_SUCCESS; +} + +static long snat_cand_ip_query_cb_del(void *data, const uchar *key, uint size, void *user_args) +{ + struct snat_cand_ip_query_cb_del_args *args = (struct snat_cand_ip_query_cb_del_args *)user_args; + struct ip_mgr_handle *handle = args->handle; + uint32_t ip = args->ip; + int group_id = args->group_id; + void *logger = handle->logger; + char ip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(ip, ip_str); + if(data == NULL) + { + MGW_LOG_ERROR(logger, "MESA_htable: key not existed, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + MGW_LOG_ERROR(logger, "Failed at del ip from snat_cand_ip_group, group_id not existed, ip is %s, group_id is %d", ip_str, group_id); + return MGW_HTABLE_QUERY_CB_SUCCESS; + } + else + { + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + struct snat_cand_ip_group *ip_group = (struct snat_cand_ip_group *)data; + int num = ip_group->num; + int pos = -1; + for(int i = 0; i < num; i++) + { + if(ip_group->ip_list[i]->ip == ip) { - MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, group_id is %d, rtn is %d", "cand_ip_group_htable", group_id, rtn); - return; + pos = i; + break; } - MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, group_id is %d", "cand_ip_group_htable", group_id); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_element_num, FS_OP_ADD, 1); + } + if(pos == -1) + { + MGW_LOG_ERROR(logger, "Failed at del ip from snat_cand_ip_group, ip not in group, ip is %s, group_id is %d", ip_str, group_id); } else { - MGW_LOG_INFO(logger, "MESA_htable: key not existed, table is %s, group_id is %d", "cand_ip_group_htable", group_id); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + FREE(&(ip_group->ip_list[pos])); + ip_group->num --; + for(int i = pos; i < num - 1; i++) + { + ip_group->ip_list[i] = ip_group->ip_list[i + 1]; + } } - struct ip_mgr_cand_ip_detail *_cand_ip = ALLOC(struct ip_mgr_cand_ip_detail, 1); - _cand_ip->ip = ip; - _cand_ip->reference = 0; - struct ip_mgr_vxlan_info *vxlan_info = ALLOC(struct ip_mgr_vxlan_info, 1); - - strncpy(vxlan_info->vxlan_outer_local_port, outer_sport, IP_MGR_PORT_LEN); - strncpy(vxlan_info->vxlan_outer_gdev_port, outer_dport, IP_MGR_PORT_LEN); - strncpy(vxlan_info->vxlan_outer_local_ip, outer_sip, IP_MGR_IP_LEN); - strncpy(vxlan_info->vxlan_outer_gdev_ip, outer_dip, IP_MGR_IP_LEN); - strncpy(vxlan_info->vxlan_outer_local_mac, outer_smac, IP_MGR_MAC_LEN); - strncpy(vxlan_info->vxlan_outer_gdev_mac, outer_dmac, IP_MGR_MAC_LEN); - strncpy(vxlan_info->vxlan_inner_smac, inner_smac, IP_MGR_MAC_LEN); - strncpy(vxlan_info->vxlan_inner_dmac, inner_dmac, IP_MGR_MAC_LEN); - vxlan_info->vxlan_link_id = link_id; - vxlan_info->vxlan_link_dir = direction; - vxlan_info->vxlan_encap_type = encap_type; - vxlan_info->vxlan_vpn_id = vpn_id; - - _cand_ip->vxlan_info = vxlan_info; - _cand_ip->mrl_ip = inet_addr(mrl_ip); - int num = ip_group->num; - ip_group->ip_list[num] = ip; - ip_group->num ++; - - //add to cand_ip_detail_htable - int rtn = MESA_htable_add(handle->cand_ip_detail_htable, (const unsigned char *)&ip, sizeof(ip), (void *)_cand_ip); - if(rtn < 0 && rtn != MESA_HTABLE_RET_DUP_ITEM) + if(ip_group->num <= 0) { - MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, ip is %s, rtn is %d", "cand_ip_detail_htable", rtn); - return; + int rtn = MESA_htable_del(handle->snat_cand_ip_htable, (const unsigned char *)&group_id, sizeof(group_id), NULL); + if(rtn < 0) + { + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at del, table is %s, group_id is %d, rtn is %d", "snat_cand_ip_htable", group_id, rtn); + } + else + { + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, group_id is %d", "snat_cand_ip_htable", group_id); + } } - if(rtn >= 0) + return MGW_HTABLE_QUERY_CB_SUCCESS; + } +} + +static void Maat_snat_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 IR_CANDIDATE_IP"); + int config_id, group_id, addr_type, location, is_valid; + char ip_addr[MGW_SYMBOL_MAX]; + sscanf(table_line, "%d %d %d %s %d %d", &config_id, &group_id, &addr_type, ip_addr, &location, &is_valid); + uint32_t ip = inet_addr(ip_addr); + if(is_valid == 1) + { + //add cand ip to snat_cand_ip_htable + struct snat_cand_ip_query_cb_add_args args; + args.handle = handle; + args.group_id = group_id; + args.ip_detail.ip = ip; + args.ip_detail.group_id = group_id; + args.ip_detail.addr_type = addr_type; + args.ip_detail.location = location; + long cb_rtn = -1; + MESA_htable_search_cb(handle->snat_cand_ip_htable, (const unsigned char *)(&group_id), sizeof(group_id), snat_cand_ip_query_cb_add, (void *)&args, &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + } + else + { + //delete cand ip from snat_cand_ip_htable + struct snat_cand_ip_query_cb_del_args args; + args.group_id = group_id; + args.handle = handle; + args.ip = ip; + long cb_rtn = -1; + MESA_htable_search_cb(handle->snat_cand_ip_htable, (const unsigned char *)(&group_id), sizeof(group_id), snat_cand_ip_query_cb_del, (void *)&args, &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_cand_ip, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + } + return; +} + + +static void Maat_snat_cand_ip_finish_cb(void* args) +{ + struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args; + void *logger = handle->logger; + MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is CAND_IP_TABLE"); + return; +} + + +static void Maat_dnat_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 IP_DNAT_POLICY"); + return; +} + +static void Maat_dnat_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 IP_DNAT_POLICY"); + int config_id, addr_type, orig_proto, do_log, action, service_id, is_valid; + char orig_ip[MGW_SYMBOL_MAX]; + int temp_orig_port; + uint16_t orig_port; + char trans_ip[MGW_SYMBOL_MAX]; + int temp_trans_port; + uint16_t trans_port; + //printf("table line is %s\n", table_line); + sscanf(table_line, "%d %d %s %d %d %s %d %d %d %d %d", &config_id, &addr_type, orig_ip, &temp_orig_port, &orig_proto, + trans_ip, &temp_trans_port, &do_log, &action, &service_id, &is_valid); + orig_port = (uint16_t)temp_orig_port; + trans_port = (uint16_t)temp_trans_port; + struct dnat_policy_htable_key *key = ALLOC(struct dnat_policy_htable_key, 1); + key->orig_ip = inet_addr(orig_ip); + key->orig_port = htons(orig_port); + if(is_valid == 1) + { + //add dnat_policy_htable + struct dnat_policy_htable_value *value = ALLOC(struct dnat_policy_htable_value, 1); + int rtn = MESA_htable_add(handle->dnat_policy_htable, (const unsigned char *)key, sizeof(key), (void *)value); + if(rtn < 0) { - MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, ip is %s", "cand_ip_detail_htable", ip_addr); - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_element_num, FS_OP_ADD, 1); + FREE(&value); + if(rtn != MESA_HTABLE_RET_DUP_ITEM) + { + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at add, table is %s, original pair is <%s:%d>, translated pair is <%s:%d>, rtn is %d", + "dnat_policy_htable", orig_ip, orig_port, trans_ip, trans_port, rtn); + } + } + else + { + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at add, table is %s, original pair is <%s:%d>, translated pair is <%s:%d>", + "dnat_policy_htable", orig_ip, orig_port, trans_ip, trans_port, rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_policy, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); } } else { - //delete from cand_ip_group_htable - struct cand_ip_group_htable_value *ip_group = NULL; - ip_group = (struct cand_ip_group_htable_value *)MESA_htable_search(handle->cand_ip_group_htable, (const unsigned char *)(&group_id), sizeof(group_id)); - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(ip_group == NULL) + //del dnat_policy_htable + int rtn = MESA_htable_del(handle->dnat_policy_htable, (const unsigned char *)key, sizeof(key), NULL); + if(rtn < 0) { - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_ERROR(logger, "MESA_htable: Failed at del ip from ip_group, group_id %d not existed in cand_ip_group_htable", group_id); - return; + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at del, table is %s, original pair is <%s:%d>, translated pair is <%s:%d>, rtn is %d", + "dnat_policy_htable", orig_ip, orig_port, trans_ip, trans_port, rtn); } - FS_operate(fs_handle->handle, fs_handle->line_ip_group, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - int rtn = delete_ip_from_group(ip, ip_group); - if(rtn == -1) + else { - MGW_LOG_ERROR(logger, "MESA_htable: Failed at del ip from ip_group, ip %s not in group %d", ip_addr, group_id); - return; + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, original pair is <%s:%d>, translated pair is <%s:%d>", + "dnat_policy_htable", orig_ip, orig_port, trans_ip, trans_port); } + } + FREE(&key); + return; +} + + +static void Maat_dnat_policy_finish_cb(void* args) +{ + struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args; + void *logger = handle->logger; + MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is IP_DNAT_POLICY"); + return; +} + +static void Maat_mrl_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 IP_MRL_IP_INFO"); + return; +} - //delete from cand_ip_detail_htable - struct ip_mgr_cand_ip_detail *cand_ip = NULL; - cand_ip = (struct ip_mgr_cand_ip_detail *)MESA_htable_search(handle->cand_ip_detail_htable, (const unsigned char *)(&ip), sizeof(ip)); - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(cand_ip == NULL) +static void Maat_mrl_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 IP_MRL_IP_INFO"); + int config_id, back_type, is_valid; + char back_ip[MGW_SYMBOL_MAX]; + char mrl_ip[MGW_SYMBOL_MAX]; + uint32_t key = inet_addr(back_ip); + //printf("table line is %s\n", table_line); + sscanf(table_line, "%d %s %d %s %d", &config_id, back_ip, &back_type, mrl_ip, &is_valid); + if(is_valid == 1) + { + //add snat_policy_htable + struct mrl_ip_htable_value *value = ALLOC(struct mrl_ip_htable_value, 1); + value->back_ip = key; + value->mrl_ip = inet_addr(mrl_ip); + int rtn = MESA_htable_add(handle->mrl_ip_htable, (const unsigned char *)&key, sizeof(key), (void *)value); + if(rtn < 0) { - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_ERROR(logger, "MESA_htable: Failed at del ip from cand_ip_detail_htable, key %s not existed", ip_addr); - return; + FREE(&value); + if(rtn != MESA_HTABLE_RET_DUP_ITEM) + { + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at add, table is %s, back_ip is %s, mrl_ip is %s, rtn is %d", + "mrl_ip_htable", back_ip, mrl_ip, rtn); + } } - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - rtn = MESA_htable_del(handle->cand_ip_detail_htable, (const unsigned char *)(&ip), sizeof(ip), NULL); + else + { + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at add, table is %s, back_ip is %s, mrl_ip is %s", + "mrl_ip_htable", back_ip, mrl_ip); + FS_operate(g_fs_handle->handle, g_fs_handle->line_mrl_ip, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); + } + } + else + { + //del snat_policy_htable + int rtn = MESA_htable_del(handle->mrl_ip_htable, (const unsigned char *)&key, sizeof(key), NULL); if(rtn < 0) { - MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at del, table is %s, ip is %s, rtn is %d", "cand_ip_detail_htable", ip_addr, rtn); - return; + MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at del, table is %s, back_ip is %s, mrl_ip is %s, rtn is %d", + "mrl_ip_htable", back_ip, mrl_ip, rtn); + } + else + { + MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, back_ip is %s, mrl_ip is %s", + "mrl_ip_htable", back_ip, mrl_ip); } - MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, ip is %s", "cand_ip_detail_htable", ip_addr); - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_element_num, FS_OP_ADD, -1); } return; } -static void Maat_cand_ip_finish_cb(void* args) +static void Maat_mrl_ip_finish_cb(void* args) { struct ip_mgr_handle *handle = (struct ip_mgr_handle *)args; void *logger = handle->logger; - MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is CAND_IP_TABLE"); - //Maat_feather_t feather = handle->feather; - /* - 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); - */ + MGW_LOG_INFO(logger, "Maat_redis: finish callback, table is IP_MRL_IP_INFO"); return; } @@ -378,24 +685,90 @@ static int Maat_plugin_register(Maat_feather_t feather, const char* table_name, return 0; } +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(logger, "Failed at Maat_set_feather_opt, type is %d, rtn is %d", type, rtn); + exit(EXIT_FAILURE); + } +} + +static Maat_feather_t Maat_init(const char *profile, const char *section, void *logger) +{ + // load conf + char table_info_path[MGW_PATH_MAX]; + int max_thread_num; + char Maat_redis_ip[MGW_SYMBOL_MAX]; + int Maat_redis_port; + int Maat_redis_index; + char stat_file_path[MGW_PATH_MAX]; + 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_int_def(profile, section, "Maat_redis_index", &Maat_redis_index, 1); + 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 Maat_redis_index: %d\n" + "stat_file_path: %s", section, table_info_path, max_thread_num, Maat_redis_ip, Maat_redis_port, Maat_redis_index, stat_file_path); + // init Maat + Maat_feather_t feather = NULL; + 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(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_REDIS_INDEX, &Maat_redis_index, sizeof(Maat_redis_index)); + //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)); + //wrapped_Maat_set_feather_opt(feather, MAAT_OPT_ACCEPT_TAGS, accept_tags, strlen(accept_tags)+1); + int rtn = Maat_initiate_feather(feather); + if(unlikely(rtn < 0)) + { + MGW_LOG_ERROR(logger, "Failed at Maat_initiate_feather"); + exit(EXIT_FAILURE); + } + return feather; +} -struct ip_mgr_handle *ip_mgr_init(const char *profile, MESA_htable_handle cand_ip_detail_htable, struct field_stat_handle *fs_handle, - Maat_feather_t Maat_feather_cand, Maat_feather_t Maat_feather_policy, void *logger) +struct ip_mgr_handle *ip_mgr_init(const char *profile, struct field_stat_handle *fs_handle, void *logger) { struct ip_mgr_handle *handle = ALLOC(struct ip_mgr_handle, 1); + handle->Maat_feather_snat_policy = Maat_init(profile, "Maat_snat_policy", logger); + handle->Maat_feather_dnat_policy = Maat_init(profile, "Maat_dnat_policy", logger); + handle->Maat_feather_snat_cand_ip = Maat_init(profile, "Maat_snat_cand_ip", logger); + handle->Maat_feather_mrl_ip = Maat_init(profile, "Maat_mrl_ip", logger); handle->logger = logger; - handle->Maat_feather_cand = Maat_feather_cand; - handle->Maat_feather_policy = Maat_feather_policy; - handle->fs_handle = fs_handle; - handle->cand_ip_detail_htable = cand_ip_detail_htable; - handle->user_policy_htable = mgw_utils_create_htable(profile, "user_policy_htable", (void *)user_policy_htable_data_free_cb, NULL, logger); - handle->cand_ip_group_htable = mgw_utils_create_htable(profile, "cand_ip_group_htable", (void *)cand_ip_group_htable_data_free_cb, NULL, logger); - int rtn = Maat_plugin_register(Maat_feather_policy, "IR_SNAT_POLICY", Maat_user_policy_start_cb, Maat_user_policy_update_cb, Maat_user_policy_finish_cb, handle); + handle->snat_policy_htable = mgw_utils_create_htable(profile, "snat_policy_htable", (void *)snat_policy_htable_data_free_cb, NULL, logger); + handle->dnat_policy_htable = mgw_utils_create_htable(profile, "dnat_policy_htable", (void *)dnat_policy_htable_data_free_cb, NULL, logger); + handle->snat_cand_ip_htable = mgw_utils_create_htable(profile, "snat_cand_ip_htable", (void *)snat_cand_ip_htable_data_free_cb, NULL, logger); + handle->mrl_ip_htable = mgw_utils_create_htable(profile, "mrl_ip_htable", (void *)mrl_ip_htable_data_free_cb, NULL, logger); + g_fs_handle = fs_handle; + int rtn = Maat_plugin_register(handle->Maat_feather_snat_policy, "IR_SNAT_POLICY", Maat_snat_policy_start_cb, Maat_snat_policy_update_cb, Maat_snat_policy_finish_cb, handle); + if(rtn == -1) + { + return NULL; + } + rtn = Maat_plugin_register(handle->Maat_feather_dnat_policy, "IR_DNAT_POLICY", Maat_dnat_policy_start_cb, Maat_dnat_policy_update_cb, Maat_dnat_policy_finish_cb, handle); if(rtn == -1) { return NULL; } - rtn = Maat_plugin_register(Maat_feather_cand, "IR_CANDIDATE_IP", Maat_cand_ip_start_cb, Maat_cand_ip_update_cb, Maat_cand_ip_finish_cb, handle); + rtn = Maat_plugin_register(handle->Maat_feather_snat_cand_ip, "IR_CANDIDATE_IP", Maat_snat_cand_ip_start_cb, Maat_snat_cand_ip_update_cb, Maat_snat_cand_ip_finish_cb, handle); + if(rtn == -1) + { + return NULL; + } + rtn = Maat_plugin_register(handle->Maat_feather_mrl_ip, "IR_MRL_IP_INFO", Maat_mrl_ip_start_cb, Maat_mrl_ip_update_cb, Maat_mrl_ip_finish_cb, handle); if(rtn == -1) { return NULL; @@ -405,11 +778,15 @@ struct ip_mgr_handle *ip_mgr_init(const char *profile, MESA_htable_handle cand_i void ip_mgr_destroy(struct ip_mgr_handle *handle) { - MESA_htable_destroy(handle->user_policy_htable, NULL); - MESA_htable_destroy(handle->cand_ip_group_htable, NULL); + MESA_htable_destroy(handle->snat_policy_htable, NULL); + MESA_htable_destroy(handle->dnat_policy_htable, NULL); + MESA_htable_destroy(handle->snat_cand_ip_htable, NULL); + MESA_htable_destroy(handle->mrl_ip_htable, NULL); + Maat_burn_feather(handle->Maat_feather_snat_policy); + Maat_burn_feather(handle->Maat_feather_dnat_policy); + Maat_burn_feather(handle->Maat_feather_snat_cand_ip); + Maat_burn_feather(handle->Maat_feather_mrl_ip); FREE(&handle); } - - diff --git a/access/src/main.cpp b/access/src/main.cpp index cfdd20a..46b85a1 100644 --- a/access/src/main.cpp +++ b/access/src/main.cpp @@ -1,11 +1,15 @@ #include "mgw_utils.h" #include "vpn_monitor.h" #include "mgw_tun.h" -#include "nat.h" +#include "snat.h" +#include "dnat.h" #include "ip_mgr.h" #include "mgw_socket.h" #include "udp_server.h" + +//rx : receive from mrl +//tx: transmit to mrl struct udp_client_handle { int socket_fd; @@ -18,81 +22,19 @@ struct mgw_handle { void* logger; char *profile; - Maat_feather_t Maat_feather_cand; - Maat_feather_t Maat_feather_policy; - struct mgw_tun_handle *mgw_tun_handle_s; - struct nat_handle *nat_handle_s; - struct ip_mgr_handle *ip_mgr_handle_s; - struct udp_client_handle *udp_client_handle_s; - MESA_htable_handle cand_ip_detail_htable; + struct mgw_tun_handle *tun_handle; + struct snat_handle *_snat_handle; + struct dnat_handle *_dnat_handle; + struct ip_mgr_handle *_ip_mgr_handle; + struct udp_client_handle *_udp_client_handle; MESA_htable_handle ip2user_htable; - struct field_stat_handle *fs_handle; }; -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(logger, "Failed at Maat_set_feather_opt, type is %d, rtn is %d", type, rtn); - exit(EXIT_FAILURE); - } -} - -static Maat_feather_t Maat_init(const char *profile, const char *section, void *logger) -{ - // load conf - char table_info_path[MGW_PATH_MAX]; - int max_thread_num; - char Maat_redis_ip[MGW_SYMBOL_MAX]; - int Maat_redis_port; - int Maat_redis_index; - char stat_file_path[MGW_PATH_MAX]; - 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_int_def(profile, section, "Maat_redis_index", &Maat_redis_index, 1); - 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 Maat_redis_index: %d\n" - "stat_file_path: %s", section, table_info_path, max_thread_num, Maat_redis_ip, Maat_redis_port, Maat_redis_index, stat_file_path); - // init Maat - Maat_feather_t feather = NULL; - 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(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_REDIS_INDEX, &Maat_redis_index, sizeof(Maat_redis_index)); - //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)); - //wrapped_Maat_set_feather_opt(feather, MAAT_OPT_ACCEPT_TAGS, accept_tags, strlen(accept_tags)+1); - int rtn = Maat_initiate_feather(feather); - if(unlikely(rtn < 0)) - { - MGW_LOG_ERROR(logger, "Failed at Maat_initiate_feather"); - exit(EXIT_FAILURE); - } - return feather; -} +static struct field_stat_handle *g_fs_handle = NULL; -static void ip2user_htable_data_free_cb(void *data) +void ip2user_htable_data_free_cb(void *data) { - FREE(&data); -} - -static void cand_ip_detail_htable_data_free_cb(void *data) -{ - struct ip_mgr_cand_ip_detail *cand_ip_detail = (struct ip_mgr_cand_ip_detail *)data; - FREE(&cand_ip_detail->vxlan_info); + FS_operate(g_fs_handle->handle, g_fs_handle->line_ip2user, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); FREE(&data); } @@ -131,6 +73,9 @@ static struct field_stat_handle * fs_init(const char *profile, void *logger) char buff[128]; int value=0; handle = FS_create_handle(); + struct field_stat_handle *fs_handle= ALLOC(struct field_stat_handle, 1); + fs_handle->handle = handle; + FS_set_para(handle, HISTOGRAM_GLOBAL_BINS, FP_HISTOGRAM_BINS, strlen(FP_HISTOGRAM_BINS)+1); FS_set_para(handle, APP_NAME, app_name, strlen(app_name)+1); @@ -147,105 +92,103 @@ static struct field_stat_handle * fs_init(const char *profile, void *logger) FS_set_para(handle, MAX_STAT_FIELD_NUM, &value, sizeof(value)); //field: packet handle status - snprintf(buff, sizeof(buff),"read_from_tun"); - int field_read_from_tun = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); + snprintf(buff, sizeof(buff),"tun_read"); + fs_handle->field_tun_read = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); - snprintf(buff, sizeof(buff),"write_to_tun"); - int field_write_to_tun = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); + snprintf(buff, sizeof(buff),"tun_bypass"); + fs_handle->field_tun_bypass = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); + + snprintf(buff, sizeof(buff),"tun_write"); + fs_handle->field_tun_write = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); - snprintf(buff, sizeof(buff),"recv_from_mrl"); - int field_recv_from_mrl = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); + snprintf(buff, sizeof(buff),"rx_from_mrl"); + fs_handle->field_rx_from_mrl = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); - snprintf(buff, sizeof(buff),"send_to_mrl"); - int field_send_to_mrl = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); + snprintf(buff, sizeof(buff),"tx_to_mrl"); + fs_handle->field_tx_to_mrl = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); - snprintf(buff,sizeof(buff),"snat_succ_rate"); + snprintf(buff,sizeof(buff),"rx_succ_rate"); FS_register_ratio(handle, - field_send_to_mrl, - field_read_from_tun, + fs_handle->field_rx_from_mrl, + fs_handle->field_tun_write, 1, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); - - snprintf(buff,sizeof(buff),"dnat_succ_rate"); + + snprintf(buff,sizeof(buff),"tx_succ_rate"); FS_register_ratio(handle, - field_write_to_tun, - field_recv_from_mrl, + fs_handle->field_tun_read, + fs_handle->field_tx_to_mrl, 1, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); + //column: cache hit/miss, line htable - snprintf(buff,sizeof(buff),"snat"); - int line_snat = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + snprintf(buff,sizeof(buff),"snat_rx"); + fs_handle->line_snat_rx = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); - snprintf(buff,sizeof(buff),"dnat"); - int line_dnat = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + snprintf(buff,sizeof(buff),"snat_tx"); + fs_handle->line_snat_tx = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + + snprintf(buff,sizeof(buff),"dnat_rx"); + fs_handle->line_dnat_rx = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + + snprintf(buff,sizeof(buff),"dnat_tx"); + fs_handle->line_dnat_tx = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); snprintf(buff,sizeof(buff),"ip2user"); - int line_ip2user = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + fs_handle->line_ip2user = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + + snprintf(buff,sizeof(buff),"snat_policy"); + fs_handle->line_snat_policy = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); - snprintf(buff,sizeof(buff),"user_policy"); - int line_user_policy = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + snprintf(buff,sizeof(buff),"dnat_policy"); + fs_handle->line_dnat_policy = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); - snprintf(buff,sizeof(buff),"ip_group"); - int line_ip_group = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + snprintf(buff,sizeof(buff),"snat_cand_ip"); + fs_handle->line_snat_cand_ip = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); - snprintf(buff,sizeof(buff),"ip_detail"); - int line_ip_detail = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); + snprintf(buff,sizeof(buff),"mrl_ip"); + fs_handle->line_mrl_ip = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); snprintf(buff,sizeof(buff),"query_num"); - int cloumn_queyr_num = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + fs_handle->cloumn_query_num = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); snprintf(buff,sizeof(buff),"element_num"); - int cloumn_element_num = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + fs_handle->cloumn_element_num = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); snprintf(buff,sizeof(buff),"cache_miss"); - int cloumn_cache_miss = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + fs_handle->cloumn_cache_miss = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); snprintf(buff,sizeof(buff),"cache_hit"); - int cloumn_cache_hit = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + fs_handle->cloumn_cache_hit = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); snprintf(buff,sizeof(buff),"cache_hit_rate"); FS_register_ratio(handle, - cloumn_cache_hit, - cloumn_queyr_num, + fs_handle->cloumn_cache_hit, + fs_handle->cloumn_query_num, 1, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); //snat/dnat latency - snprintf(buff,sizeof(buff), "snat(us)"); - int snat_latency = FS_register_histogram(handle, FS_CALC_CURRENT, buff, 1, 30*1000, 3); + snprintf(buff,sizeof(buff), "snat_rx(us)"); + fs_handle->snat_rx_latency = FS_register_histogram(handle, FS_CALC_CURRENT, buff, 1, 30*1000, 3); - snprintf(buff,sizeof(buff), "dnat(us)"); - int dnat_latency = FS_register_histogram(handle, FS_CALC_CURRENT, buff, 1, 30*1000, 3); + snprintf(buff,sizeof(buff), "snat_tx(us)"); + fs_handle->snat_tx_latency = FS_register_histogram(handle, FS_CALC_CURRENT, buff, 1, 30*1000, 3); + + snprintf(buff,sizeof(buff), "dnat_rx(us)"); + fs_handle->dnat_rx_latency = FS_register_histogram(handle, FS_CALC_CURRENT, buff, 1, 30*1000, 3); + + snprintf(buff,sizeof(buff), "dnat_tx(us)"); + fs_handle->dnat_tx_latency = FS_register_histogram(handle, FS_CALC_CURRENT, buff, 1, 30*1000, 3); FS_start(handle); - struct field_stat_handle *fs_handle= ALLOC(struct field_stat_handle, 1); - fs_handle->handle = handle; - //field - fs_handle->field_read_from_tun = field_read_from_tun; - fs_handle->field_write_to_tun = field_write_to_tun; - fs_handle->field_recv_from_mrl = field_recv_from_mrl; - fs_handle->field_send_to_mrl = field_send_to_mrl; - //cloumn and line - fs_handle->cloumn_cache_hit = cloumn_cache_hit; - fs_handle->cloumn_cache_miss = cloumn_cache_miss; - fs_handle->cloumn_element_num = cloumn_element_num; - fs_handle->cloumn_queyr_num = cloumn_queyr_num; - fs_handle->line_snat = line_snat; - fs_handle->line_dnat = line_dnat; - fs_handle->line_ip2user = line_ip2user; - fs_handle->line_user_policy = line_user_policy; - fs_handle->line_ip_group = line_ip_group; - fs_handle->line_ip_detail = line_ip_detail; - //snat/dnat latency - fs_handle->snat_latency = snat_latency; - fs_handle->dnat_latency = dnat_latency; return fs_handle; } @@ -278,35 +221,21 @@ static struct mgw_handle * mgw_init(char *conf_path) //init feild_stat struct field_stat_handle *fs_handle = fs_init(profile, logger); - _mgw_handle->fs_handle = fs_handle; - - //init Maat - Maat_feather_t Maat_feather_cand = Maat_init((const char *)profile, "Maat_cand", logger); - Maat_feather_t Maat_feather_policy = Maat_init((const char *)profile, "Maat_policy", logger); - _mgw_handle->Maat_feather_cand = Maat_feather_cand; - _mgw_handle->Maat_feather_policy = Maat_feather_policy; + g_fs_handle = fs_handle; //init tun - _mgw_handle->mgw_tun_handle_s = mgw_tun_init("tun_mgw", logger); + _mgw_handle->tun_handle = mgw_tun_init("tun_mgw", logger); //init ip_mgr - MESA_htable_handle cand_ip_detail_htable = mgw_utils_create_htable(profile, "cand_ip_detail_htable", (void *)cand_ip_detail_htable_data_free_cb, NULL, logger); - if(cand_ip_detail_htable == NULL) - { - MGW_LOG_ERROR(logger, "Failed at create cand_ip_detail_htable"); - exit(EXIT_FAILURE); - } - _mgw_handle->cand_ip_detail_htable = cand_ip_detail_htable; - struct ip_mgr_handle * _ip_mgr_handle = ip_mgr_init(profile, cand_ip_detail_htable, fs_handle, Maat_feather_cand, Maat_feather_policy, logger); + struct ip_mgr_handle * _ip_mgr_handle = ip_mgr_init(profile, fs_handle, logger); 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; - + _mgw_handle->_ip_mgr_handle = _ip_mgr_handle; - //init nat + //init snat MESA_htable_handle ip2user_htable = mgw_utils_create_htable(profile, "ip2user_htable", (void *)ip2user_htable_data_free_cb, NULL, logger); if(ip2user_htable == NULL) { @@ -314,8 +243,10 @@ static struct mgw_handle * mgw_init(char *conf_path) exit(EXIT_FAILURE); } _mgw_handle->ip2user_htable = ip2user_htable; - _mgw_handle->nat_handle_s = nat_init(profile, ip2user_htable, cand_ip_detail_htable, fs_handle, logger); + _mgw_handle->_snat_handle = snat_init(profile, ip2user_htable, _ip_mgr_handle, fs_handle, logger); + //init_dnat + _mgw_handle->_dnat_handle = dnat_init(profile, _ip_mgr_handle, fs_handle, logger); //create thread_vpn_monitor pthread_t thread_id; @@ -335,8 +266,9 @@ static struct mgw_handle * mgw_init(char *conf_path) struct udp_server_args *_udp_server_args = ALLOC(struct udp_server_args, 1); _udp_server_args->logger = logger; _udp_server_args->profile = profile; - _udp_server_args->_nat_handle = _mgw_handle->nat_handle_s; - _udp_server_args->tun_handle = _mgw_handle->mgw_tun_handle_s; + _udp_server_args->_snat_handle = _mgw_handle->_snat_handle; + _udp_server_args->_dnat_handle = _mgw_handle->_dnat_handle; + _udp_server_args->tun_handle = _mgw_handle->tun_handle; _udp_server_args->fs_handle = fs_handle; rtn = pthread_create(&thread_id, NULL, thread_udp_server, (void *)_udp_server_args); if(unlikely(rtn != 0)) @@ -347,7 +279,7 @@ static struct mgw_handle * mgw_init(char *conf_path) //init udp client socket struct udp_client_handle *_udp_client_handle = udp_client_init(profile, logger); - _mgw_handle->udp_client_handle_s = _udp_client_handle; + _mgw_handle->_udp_client_handle = _udp_client_handle; return _mgw_handle; } @@ -356,75 +288,88 @@ static void mgw_destroy(struct mgw_handle *handle) { MESA_destroy_runtime_log_handle(handle->logger); FREE(&handle->profile); - Maat_burn_feather(handle->Maat_feather_cand); - Maat_burn_feather(handle->Maat_feather_policy); - MESA_htable_destroy(handle->cand_ip_detail_htable, NULL); MESA_htable_destroy(handle->ip2user_htable, NULL); - mgw_tun_destroy(handle->mgw_tun_handle_s); - nat_destroy(handle->nat_handle_s); - ip_mgr_destroy(handle->ip_mgr_handle_s); - FREE(&handle->udp_client_handle_s); - FS_stop(&handle->fs_handle->handle); - FREE(&handle->fs_handle); + mgw_tun_destroy(handle->tun_handle); + snat_destroy(handle->_snat_handle); + dnat_destroy(handle->_dnat_handle); + ip_mgr_destroy(handle->_ip_mgr_handle); + FREE(&handle->_udp_client_handle); + FS_stop(&(g_fs_handle->handle)); + FREE(&g_fs_handle); FREE(&handle); } -static int send_data_to_mrl(struct udp_client_handle *handle, char *buff, int len, MESA_htable_handle cand_ip_detail_htable, - struct ip_mgr_vxlan_info *vxlan_info, uint32_t mrl_ip) +static int send_data_to_mrl(struct udp_client_handle *handle, char *buff, int len, uint32_t mrl_ip) { void *logger = handle->logger; int socket_fd = handle->socket_fd; - char _buff[MGW_PACKET_MAX]; - memcpy(_buff, vxlan_info, sizeof(struct ip_mgr_vxlan_info)); - memcpy(_buff + sizeof(struct ip_mgr_vxlan_info), buff, len); - len += sizeof(struct ip_mgr_vxlan_info); uint16_t dport = htons(handle->dport); - int rtn = mgw_socket_udp_send(socket_fd, _buff, len, mrl_ip, dport); - if (rtn < 0) + int rtn = mgw_socket_udp_send(socket_fd, buff, len, mrl_ip, dport); + if (rtn < 0 || rtn != len) { MGW_LOG_ERROR(logger, "mgw_socket: Failed at send udp data, errno is %d, %s", errno, strerror(errno)); + return rtn; } + MGW_LOG_INFO(logger, "mgw_socket: Succeed at send udp data, send len is %d", rtn); return rtn; } static void mgw_run(struct mgw_handle *handle) { - void *logger = handle->logger; + //void *logger = handle->logger; sleep(10); - struct timespec start_time, end_time; - struct field_stat_handle *fs_handle = handle->fs_handle; - //for test - //struct timespec _start_time; - //clock_gettime(CLOCK_MONOTONIC, &_start_time); - - + struct timespec start_time; while(1) { - clock_gettime(CLOCK_MONOTONIC, &start_time); char buff[MGW_PACKET_MAX]; - int len = mgw_tun_read(handle->mgw_tun_handle_s, buff, MGW_PACKET_MAX); - FS_operate(fs_handle->handle, fs_handle->field_read_from_tun, 0, FS_OP_ADD, 1); - struct ip_mgr_vxlan_info *vxlan_info = NULL; + int len = mgw_tun_read(handle->tun_handle, buff, MGW_PACKET_MAX); + if(len < 0) + { + continue; + } + FS_operate(g_fs_handle->handle, g_fs_handle->field_tun_read, 0, FS_OP_ADD, 1); uint32_t mrl_ip; - int rtn = nat_src_convert(handle->nat_handle_s, handle->ip_mgr_handle_s, buff, len, &vxlan_info, &mrl_ip); - if(rtn == NAT_COVERT_FAILURE) + clock_gettime(CLOCK_MONOTONIC, &start_time); + int rtn = dnat_tx_convert(handle->_dnat_handle, buff, len, &mrl_ip); + mgw_utils_fs_latency_cala(g_fs_handle->handle, start_time, g_fs_handle->dnat_tx_latency); + if(rtn == MGW_DROP) + { + continue; + } + if(rtn == MGW_FORWORD) + { + int rtn = send_data_to_mrl(handle->_udp_client_handle, buff, len, mrl_ip); + if(rtn > 0 && rtn == len) + { + FS_operate(g_fs_handle->handle, g_fs_handle->field_tx_to_mrl, 0, FS_OP_ADD, 1); + } + continue; + } + // rtn=MGW_BYPASS, do sant_src_convert + clock_gettime(CLOCK_MONOTONIC, &start_time); + rtn = snat_tx_convert(handle->_snat_handle, buff, len, &mrl_ip); + mgw_utils_fs_latency_cala(g_fs_handle->handle, start_time, g_fs_handle->snat_tx_latency); + if(rtn == MGW_DROP) { - MGW_LOG_ERROR(logger, "Failed at nat_src_convert"); continue; } - int send_len = send_data_to_mrl(handle->udp_client_handle_s, buff, len, handle->cand_ip_detail_htable, vxlan_info, mrl_ip); - if(send_len > 0) + if(rtn == MGW_FORWORD) { - FS_operate(fs_handle->handle, fs_handle->field_send_to_mrl, 0, FS_OP_ADD, 1); + int rtn = send_data_to_mrl(handle->_udp_client_handle, buff, len, mrl_ip); + if(rtn > 0 && rtn == len) + { + FS_operate(g_fs_handle->handle, g_fs_handle->field_tx_to_mrl, 0, FS_OP_ADD, 1); + } + continue; + } + // rtn=MGW_BYPASS, write to tun + rtn = mgw_tun_write(handle->tun_handle, buff, len); + if(rtn < 0 || rtn != len) + { + continue; } - clock_gettime(CLOCK_MONOTONIC, &end_time); - long long cost_time; - cost_time = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_nsec - start_time.tv_nsec) / 1000; - FS_operate(fs_handle->handle, fs_handle->snat_latency, 0, FS_OP_SET, cost_time); - - //for test - //if(end_time.tv_sec - _start_time.tv_sec > 60) - //break; + FS_operate(g_fs_handle->handle, g_fs_handle->field_tun_bypass, 0, FS_OP_ADD, 1); + FS_operate(g_fs_handle->handle, g_fs_handle->field_tun_read, 0, FS_OP_ADD, -1); } } diff --git a/access/src/nat.cpp b/access/src/nat.cpp deleted file mode 100644 index 1a175dc..0000000 --- a/access/src/nat.cpp +++ /dev/null @@ -1,574 +0,0 @@ -#include "mgw_utils.h" -#include "nat.h" -#include "ip_mgr.h" -//hash表超时时间设为0,不超时 -// hash表 value 为malloc - -struct nat_handle -{ - void *logger; - MESA_htable_handle ip2user_htable; // should be thread-safe - MESA_htable_handle snat_htable; - MESA_htable_handle dnat_htable; - MESA_htable_handle cand_ip_detail_htable; - struct field_stat_handle *fs_handle; - int access_id; -}; - -struct field_stat_handle *g_fs_handle; - -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 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 = _iphdr->saddr; - sess->dip = _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 = _tcphdr->source; - sess->dport = _tcphdr->dest; - break; - } - case PROTO_UDP: - { - if(len < 28) - { - return -1; - } - struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len); - sess->sport = _udphdr->source; - sess->dport = _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; - uint16_t tot_len = ntohs(_iphdr->tot_len); - uint16_t iphdr_len = _iphdr->ihl * 4; - _iphdr->saddr = pair->ip; - switch(_iphdr->protocol) - { - case PROTO_TCP: - { - struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len); - uint16_t tcp_len = tot_len - iphdr_len; - - /* test - uint16_t correct_tcp_check = _tcphdr->check; - printf("correct_tcp_check is %0x\n", correct_tcp_check); - _tcphdr->check = 0; - u_int16_t my_tcp_check = mgw_utils_tcp_checksum(_tcphdr, tcp_len, _iphdr->saddr, _iphdr->daddr); - printf("tcp_len is %d, my_tcp_check is %0x\n", tcp_len, my_tcp_check); - */ - - _tcphdr->source = pair->port; - _tcphdr->check = 0; - uint16_t tcp_checksum = mgw_utils_tcp_checksum(_tcphdr, tcp_len, _iphdr->saddr, _iphdr->daddr); - _tcphdr->check = tcp_checksum; - break; - } - case PROTO_UDP: - { - struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len); - uint16_t udp_len = tot_len - iphdr_len; - _udphdr->source = pair->port; - _udphdr->check = 0; - uint16_t udp_checksum = mgw_utils_udp_checksum(_udphdr, udp_len, _iphdr->saddr, _iphdr->daddr); - _udphdr->check = udp_checksum; - break; - } - case PROTO_ICMP: - break; - default: - break; - } - _iphdr->check = 0; - uint16_t ip_checksum = mgw_utils_ip_checksum(buff, iphdr_len); - _iphdr->check = ip_checksum; - return 0; -} - -static int packet_dest_replace(const char *buff, int len, struct ip_port_pair *pair) -{ - struct iphdr *_iphdr = (struct iphdr *)buff; - uint16_t tot_len = ntohs(_iphdr->tot_len); - uint16_t iphdr_len = _iphdr->ihl * 4; - _iphdr->daddr = pair->ip; - switch(_iphdr->protocol) - { - case PROTO_TCP: - { - struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len); - uint16_t tcp_len = tot_len - iphdr_len; - - /* test - uint16_t correct_tcp_check = _tcphdr->check; - printf("correct_tcp_check is %0x\n", correct_tcp_check); - _tcphdr->check = 0; - u_int16_t my_tcp_check = mgw_utils_tcp_checksum(_tcphdr, tcp_len, _iphdr->saddr, _iphdr->daddr); - printf("tcp_len is %d, my_tcp_check is %0x\n", tcp_len, my_tcp_check); - */ - - _tcphdr->dest = pair->port; - _tcphdr->check = 0; - uint16_t tcp_checksum = mgw_utils_tcp_checksum(_tcphdr, tcp_len, _iphdr->saddr, _iphdr->daddr); - _tcphdr->check = tcp_checksum; - break; - } - case PROTO_UDP: - { - struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len); - uint16_t udp_len = tot_len - iphdr_len; - _udphdr->dest = pair->port; - _udphdr->check = 0; - uint16_t udp_checksum = mgw_utils_udp_checksum(_udphdr, udp_len, _iphdr->saddr, _iphdr->daddr); - _udphdr->check = udp_checksum; - break; - } - case PROTO_ICMP: - break; - default: - break; - } - _iphdr->check = 0; - uint16_t ip_checksum = mgw_utils_ip_checksum(buff, iphdr_len); - _iphdr->check = ip_checksum; - return 0; -} - -static void snat_htable_data_free_cb(void *data) -{ - //printf("call snat_htable_data_free_cb\n"); - FS_operate(g_fs_handle->handle, g_fs_handle->line_snat, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); - FREE(&data); -} - -static void dnat_htable_data_free_cb(void *data) -{ - //printf("call dnat_htable_data_free_cb\n"); - FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); - FREE(&data); -} - - -struct nat_handle * nat_init(const char *profile, MESA_htable_handle ip2user_htable, MESA_htable_handle cand_ip_detail_htable, - struct field_stat_handle *fs_handle, void *logger) -{ - struct nat_handle *handle = ALLOC(struct nat_handle, 1); - handle->logger = logger; - handle->fs_handle = fs_handle; - handle->ip2user_htable = ip2user_htable; - handle->cand_ip_detail_htable = cand_ip_detail_htable; - handle->snat_htable = mgw_utils_create_htable(profile, "snat_htable", (void *)snat_htable_data_free_cb, NULL, logger); - handle->dnat_htable = mgw_utils_create_htable(profile, "dnat_htable", (void *)dnat_htable_data_free_cb, NULL, logger); - handle->access_id = 0; - g_fs_handle = fs_handle; - return handle; -} - -void nat_destroy(struct nat_handle *handle) -{ - MESA_htable_destroy(handle->snat_htable, NULL); - MESA_htable_destroy(handle->dnat_htable, NULL); - 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 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, uint32_t cand_ip) -{ - u_int16_t random = mgw_utils_get_random(64); - uint16_t hash = ntohl(sess->dip) ^ ntohl(cand_ip) ^ ntohs(sess->dport) ^ (sess->proto); - hash &= 0xff; - uint16_t port = (access_id << 14) + (random << 8) + hash; - /* - #ifdef DEBUG - printf("test_hash: dip is %0x, dport is %0x, cand_ip is %0x, proto is %0x, generate port is %0x\n", - ntohl(sess->dip), ntohs(sess->dport), ntohl(cand_ip), sess->proto, port); - #endif - */ - return htons(port); -} - -//get snat_value, if succeed, has already added to dnat_htable -static struct ip_port_pair * snat_value_get(struct nat_handle *handle, struct ip_mgr_handle *_ip_mgr_handle, const char *user_name, - struct session *snat_key, struct ip_mgr_vxlan_info **vxlan_info, uint32_t *mrl_ip) -{ - struct field_stat_handle *fs_handle = handle->fs_handle; - int retry_times = 10; - void *logger = handle->logger; - struct session *dnat_key = ALLOC(struct session, 1); - dnat_key->sip = snat_key->dip; - dnat_key->sport = snat_key->dport; - dnat_key->proto = snat_key->proto; - struct ip_port_pair *snat_value = ALLOC(struct ip_port_pair, 1); - struct ip_port_pair *dnat_value = ALLOC(struct ip_port_pair, 1); - dnat_value->ip = snat_key->sip; - dnat_value->port = snat_key->sport; - char dnat_key_sip[MGW_SYMBOL_MAX]; - char dnat_key_dip[MGW_SYMBOL_MAX]; - char dnat_value_ip[MGW_SYMBOL_MAX]; - mgw_utils_inet_ntoa(dnat_key->sip, dnat_key_sip); - mgw_utils_inet_ntoa(dnat_value->ip, dnat_value_ip); - for(int i = 0; i < retry_times; i++) - { - uint32_t cand_ip; - int rtn = ip_mgr_candidata_ip_get(_ip_mgr_handle, user_name, &cand_ip); - if(rtn < 0) - { - MGW_LOG_INFO(logger, "Failed to find ip and port, user_name is %s", user_name); - FREE(&dnat_key); - FREE(&dnat_value); - FREE(&snat_value); - return NULL; - } - u_int16_t port = get_candidate_port(handle->access_id, snat_key, cand_ip); - dnat_key->dip = cand_ip; - dnat_key->dport = port; - snat_value->ip = cand_ip; - snat_value->port = port; - mgw_utils_inet_ntoa(dnat_key->dip, dnat_key_dip); - // check if cand_ip is still valid - struct ip_mgr_cand_ip_detail *cand_ip_detail = NULL; - cand_ip_detail = (struct ip_mgr_cand_ip_detail *)MESA_htable_search(handle->cand_ip_detail_htable, (const unsigned char *)(&cand_ip), sizeof(cand_ip)); - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - char _ip[MGW_SYMBOL_MAX]; - mgw_utils_inet_ntoa(cand_ip, _ip); - if(cand_ip_detail == NULL) - { - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_ERROR(logger, "MESA_htable: table is %s, key %s not existed", "cand_ip_detail_htable", _ip); - continue; - } - MGW_LOG_INFO(logger, "MESA_htable: table is %s, key %s existed", "cand_ip_detail_htable", _ip); - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - - //try to add to dnat - rtn = MESA_htable_add(handle->dnat_htable, (const unsigned char *)dnat_key, sizeof(struct session), (void *)dnat_value); - if(rtn < 0 && rtn != MESA_HTABLE_RET_DUP_ITEM) - { - MGW_LOG_ERROR(logger, "MESA_htable: Failed at add to %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>, rtn is %d", "dnat_htable", - dnat_key_sip, ntohs(dnat_key->sport), dnat_key_dip, ntohs(dnat_key->dport), dnat_key->proto, dnat_value_ip, ntohs(dnat_value->port), rtn); - continue; - } - if(rtn == MESA_HTABLE_RET_DUP_ITEM) - { - MGW_LOG_INFO(logger, "Selected ip and port <%s:%d> conflict", dnat_key_dip, ntohs(dnat_key->dport)); - continue; - } - //rtn >= 0, succeed to add to dnat - MGW_LOG_INFO(logger, "MESA_htable: Succeed at add to %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "dnat_htable", - dnat_key_sip, ntohs(dnat_key->sport), dnat_key_dip, ntohs(dnat_key->dport), dnat_key->proto, dnat_value_ip, ntohs(dnat_value->port)); - FS_operate(fs_handle->handle, fs_handle->line_dnat, fs_handle->cloumn_element_num, FS_OP_ADD, 1); - //reference + 1, when to --? - cand_ip_detail->reference ++; - *vxlan_info = cand_ip_detail->vxlan_info; - *mrl_ip = cand_ip_detail->mrl_ip; - FREE(&dnat_key); - return snat_value; - } - MGW_LOG_ERROR(logger, "Failed to find ip and port, retry times is %d", retry_times - 1); - FREE(&dnat_key); - FREE(&dnat_value); - FREE(&snat_value); - return NULL; -} - -int nat_src_convert(struct nat_handle *handle, struct ip_mgr_handle *_ip_mgr_handle, char *buff, int len, - struct ip_mgr_vxlan_info **vxlan_info, uint32_t *mrl_ip) -{ - struct field_stat_handle *fs_handle = handle->fs_handle; - void *logger = handle->logger; - //get session - struct session *snat_key = ALLOC(struct session, 1); - 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); - FREE(&snat_key); - return NAT_COVERT_FAILURE; - } - char snat_key_sip[MGW_SYMBOL_MAX]; - char snat_key_dip[MGW_SYMBOL_MAX]; - char snat_value_ip[MGW_SYMBOL_MAX]; - mgw_utils_inet_ntoa(snat_key->sip, snat_key_sip); - mgw_utils_inet_ntoa(snat_key->dip, snat_key_dip); - - //for test - /* - if(strncmp(snat_key_dip, "61.135.169.121", MGW_SYMBOL_MAX) != 0) - { - return NAT_COVERT_FAILURE; - } - */ - - MGW_LOG_INFO(logger, "Before snat: session is <%s:%d %s:%d %d>", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto); - //query snat_htable,get ip_port pair - long snat_cb_rtn = -1; - struct ip_port_pair *snat_value = ALLOC(struct ip_port_pair, 1); - MESA_htable_search_cb(handle->snat_htable, (const unsigned char *)(snat_key), sizeof(struct session), snat_htable_query_cb, (void *)(snat_value), &snat_cb_rtn); - FS_operate(fs_handle->handle, fs_handle->line_snat, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(snat_cb_rtn == HTABLE_KEY_EXISTED) - { - FS_operate(fs_handle->handle, fs_handle->line_snat, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - mgw_utils_inet_ntoa(snat_value->ip, snat_value_ip); - MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, key is <%s:%d %s:%d %d>, value is <%s, %d>", "snat_htable", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto, snat_value_ip, ntohs(snat_value->port)); - struct ip_mgr_cand_ip_detail *cand_ip_detail = NULL; - cand_ip_detail = (struct ip_mgr_cand_ip_detail *)MESA_htable_search(handle->cand_ip_detail_htable, (const unsigned char *)(&(snat_value->ip)), sizeof(snat_value->ip)); - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(cand_ip_detail != NULL) - { - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - MGW_LOG_INFO(handle->logger, "MESA_htable, key existed, table is %s, key is %s", "cand_ip_detail_htable", snat_value_ip); - packet_src_replace(buff, len, snat_value); - //after snat - rtn = sess_get_from_packet(buff, len, snat_key); - if(rtn == -1) - { - MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len); - FREE(&snat_key); - FREE(&snat_value); - return NAT_COVERT_FAILURE; - } - MGW_LOG_INFO(logger, "After snat: session is <%s:%d %s:%d %d>", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto); - *vxlan_info = cand_ip_detail->vxlan_info; - *mrl_ip = cand_ip_detail->mrl_ip; - FREE(&snat_key); - FREE(&snat_value); - return NAT_COVERT_SUCCESS; - } - else - { - FS_operate(fs_handle->handle, fs_handle->line_ip_detail, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_INFO(handle->logger, "MESA_htable, key not existed, table is %s, key is %s", "cand_ip_detail_htable", snat_value_ip); - //if session exists in sant but ip is valid. del session from snat, do not del dnat - rtn = MESA_htable_del(handle->snat_htable, (const unsigned char *)(snat_key), sizeof(struct session), NULL); - if(rtn < 0 && rtn != MESA_HTABLE_RET_NOT_FOUND) - { - MGW_LOG_ERROR(handle->logger, "MESA_htable: Failed at del, rtn is %d, table is %s, key is <%s:%d %s,%d, %d>", rtn, "snat_htable", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto); - FREE(&snat_key); - FREE(&snat_value); - return NAT_COVERT_FAILURE;; - } - MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, key is <%s:%d %s,%d, %d>", "snat_htable", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto); - } - } - //do snat - FS_operate(fs_handle->handle, fs_handle->line_snat, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - FREE(&snat_value); - uint32_t sip = snat_key->sip; - char *user_name = NULL; - user_name = (char *)MESA_htable_search(handle->ip2user_htable, (const unsigned char *)(&sip), sizeof(sip)); - FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(user_name != NULL) - { - FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - snat_value = snat_value_get(handle, _ip_mgr_handle, user_name, snat_key, vxlan_info, mrl_ip); - if(snat_value == NULL) - { - FREE(&snat_key); - FREE(&snat_value); - return NAT_COVERT_FAILURE; - } - //add sess to snat - rtn = MESA_htable_add(handle->snat_htable, (const unsigned char *)(snat_key), sizeof(struct session), (const void*)snat_value); - mgw_utils_inet_ntoa(snat_value->ip, snat_value_ip); - if(rtn < 0) - { - MGW_LOG_ERROR(logger, "MESA_htable: Failed at add to %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>, rtn is %d", "snat_htable", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto, snat_value_ip, ntohs(snat_value->port), rtn); - FREE(&snat_key); - FREE(&snat_value); - return NAT_COVERT_FAILURE; - } - FS_operate(fs_handle->handle, fs_handle->line_snat, fs_handle->cloumn_element_num, FS_OP_ADD, 1); - MGW_LOG_INFO(logger, "MESA_htable: Succeed at add to %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "snat_htable", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto, snat_value_ip, ntohs(snat_value->port)); - packet_src_replace(buff, len, snat_value); - rtn = sess_get_from_packet(buff, len, snat_key); - if(rtn == -1) - { - MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len); - FREE(&snat_key); - return NAT_COVERT_FAILURE; - } - mgw_utils_inet_ntoa(snat_key->sip, snat_key_sip); - mgw_utils_inet_ntoa(snat_key->dip, snat_key_dip); - MGW_LOG_INFO(logger, "After snat: session is <%s:%d %s:%d %d>", - snat_key_sip, ntohs(snat_key->sport), snat_key_dip, ntohs(snat_key->dport), snat_key->proto); - FREE(&snat_key); - return NAT_COVERT_SUCCESS; - } - else - { - FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_ERROR(logger, "Failed at find user_name, ip %s", snat_key_sip); - FREE(&snat_key); - return NAT_COVERT_FAILURE; - } - FREE(&snat_key); - return NAT_COVERT_FAILURE; -} - - -int nat_dest_convert(struct nat_handle *handle, char *buff, int len) -{ - struct field_stat_handle *fs_handle = handle->fs_handle; - void *logger = handle->logger; - //get session - struct session *dnat_key = ALLOC(struct session, 1); - int rtn = sess_get_from_packet(buff, len, dnat_key); - if(rtn == -1) - { - MGW_LOG_ERROR(logger, "Failed at nat_dest_convert: parse packet failed, packet len is %d", len); - FREE(&dnat_key); - return NAT_COVERT_FAILURE; - } - char dnat_key_sip[MGW_SYMBOL_MAX]; - char dnat_key_dip[MGW_SYMBOL_MAX]; - char dnat_value_ip[MGW_SYMBOL_MAX]; - mgw_utils_inet_ntoa(dnat_key->sip, dnat_key_sip); - mgw_utils_inet_ntoa(dnat_key->dip, dnat_key_dip); - MGW_LOG_INFO(logger, "Before dnat: session is <%s:%d %s:%d %d>", - dnat_key_sip, ntohs(dnat_key->sport), dnat_key_dip, ntohs(dnat_key->dport), dnat_key->proto); - - //query dnat,get ip and port - long dnat_cb_rtn = -1; - struct ip_port_pair dnat_value; - MESA_htable_search_cb(handle->dnat_htable, (const unsigned char *)(dnat_key), sizeof(struct session), dnat_htable_query_cb, (void *)(&dnat_value), &dnat_cb_rtn); - FS_operate(fs_handle->handle, fs_handle->line_dnat, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); - if(dnat_cb_rtn == HTABLE_KEY_EXISTED) - { - FS_operate(fs_handle->handle, fs_handle->line_dnat, fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); - mgw_utils_inet_ntoa(dnat_value.ip, dnat_value_ip); - MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, key is <%s:%d %s,%d, %d>, value is <%s, %d>", "dnat_htable", - dnat_key_sip, ntohs(dnat_key->sport), dnat_key_dip, ntohs(dnat_key->dport), dnat_key->proto, dnat_value_ip, ntohs(dnat_value.port)); - packet_dest_replace(buff, len, &dnat_value); - rtn = sess_get_from_packet(buff, len, dnat_key); - if(rtn == -1) - { - MGW_LOG_ERROR(logger, "Failed at nat_dest_convert: parse packet failed, packet len is %d", len); - FREE(&dnat_key); - return NAT_COVERT_FAILURE; - } - mgw_utils_inet_ntoa(dnat_key->sip, dnat_key_sip); - mgw_utils_inet_ntoa(dnat_key->dip, dnat_key_dip); - MGW_LOG_INFO(logger, "After dnat: session is <%s:%d %s:%d %d>", - dnat_key_sip, ntohs(dnat_key->sport), dnat_key_dip, ntohs(dnat_key->dport), dnat_key->proto); - FREE(&dnat_key); - return NAT_COVERT_SUCCESS; - } - else - { - FS_operate(fs_handle->handle, fs_handle->line_dnat, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - MGW_LOG_INFO(logger, "MESA_htable: key not existed, table is %s, key is <%s:%d %s:%d %d>", "dnat_htable", - dnat_key_sip, ntohs(dnat_key->sport), dnat_key_dip, ntohs(dnat_key->dport), dnat_key->proto); - FREE(&dnat_key); - return NAT_COVERT_FAILURE; - } -} diff --git a/access/src/snat.cpp b/access/src/snat.cpp new file mode 100644 index 0000000..63f9340 --- /dev/null +++ b/access/src/snat.cpp @@ -0,0 +1,339 @@ +#include "mgw_utils.h" +#include "snat.h" +#include "ip_mgr.h" + +struct snat_handle +{ + void *logger; + struct ip_mgr_handle *_ip_mgr_handle; + MESA_htable_handle ip2user_htable; // should be thread-safe + MESA_htable_handle snat_tx_htable; + MESA_htable_handle snat_rx_htable; + int access_id; +}; + +struct snat_tx_htable_value +{ + struct mgw_utils_sess sess; + uint32_t mrl_ip; +}; + +struct field_stat_handle *g_fs_handle; + + +static void snat_tx_htable_data_free_cb(void *data) +{ + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_tx, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); + FREE(&data); +} + +static void dnat_rx_htable_data_free_cb(void *data) +{ + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_element_num, FS_OP_ADD, -1); + FREE(&data); +} + + +struct snat_handle * snat_init(const char *profile, MESA_htable_handle ip2user_htable, struct ip_mgr_handle *_ip_mgr_handle, + struct field_stat_handle *fs_handle, void *logger) +{ + struct snat_handle *handle = ALLOC(struct snat_handle, 1); + handle->logger = logger; + handle->_ip_mgr_handle = _ip_mgr_handle; + handle->ip2user_htable = ip2user_htable; + handle->snat_tx_htable = mgw_utils_create_htable(profile, "snat_tx_htable", (void *)snat_tx_htable_data_free_cb, NULL, logger); + handle->snat_rx_htable = mgw_utils_create_htable(profile, "dnat_rx_htable", (void *)dnat_rx_htable_data_free_cb, NULL, logger); + char *section = (char *)"global"; + MESA_load_profile_int_def(profile, section, "access_id", &handle->access_id, 0); + g_fs_handle = fs_handle; + return handle; +} + +void snat_destroy(struct snat_handle *handle) +{ + MESA_htable_destroy(handle->snat_tx_htable, NULL); + MESA_htable_destroy(handle->snat_rx_htable, NULL); + FREE(&handle); +} + +static long snat_tx_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg) +{ + struct snat_tx_htable_value *dup_value = (struct snat_tx_htable_value *)user_arg; + if(data != NULL) + { + struct snat_tx_htable_value *_data = (struct snat_tx_htable_value *)data; + dup_value->sess.proto = _data->sess.proto; + dup_value->sess.sip = _data->sess.sip; + dup_value->sess.sport = _data->sess.sport; + dup_value->sess.dip = _data->sess.dip; + dup_value->sess.dport = _data->sess.dport; + dup_value->mrl_ip = _data->mrl_ip; + return MGW_HTABLE_KEY_EXISTED; + } + else + { + return MGW_HTABLE_KEY_NOT_EXISTED; + } +} + +static long snat_rx_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg) +{ + struct mgw_utils_sess *dup_value = (struct mgw_utils_sess *)user_arg; + if(data != NULL) + { + struct mgw_utils_sess *_data = (struct mgw_utils_sess *)data; + dup_value->proto = _data->proto; + dup_value->sip = _data->sip; + dup_value->sport = _data->sport; + dup_value->dip = _data->dip; + dup_value->dport = _data->dport; + return MGW_HTABLE_KEY_EXISTED; + } + else + { + return MGW_HTABLE_KEY_NOT_EXISTED; + } +} + +static long ip2user_htable_query_cb(void *data, const uchar *key, uint size, void *user_arg) +{ + char *dup_value = (char *)user_arg; + if(data != NULL) + { + char *_data = (char *)data; + strncpy(dup_value, _data, MGW_SYMBOL_MAX); + return MGW_HTABLE_KEY_EXISTED; + } + else + { + return MGW_HTABLE_KEY_NOT_EXISTED; + } +} + +static uint16_t get_candidate_port(int access_id, struct mgw_utils_sess *sess, uint32_t cand_ip) +{ + u_int16_t random = mgw_utils_get_random(64); + uint16_t hash = ntohl(sess->dip) ^ ntohl(cand_ip) ^ ntohs(sess->dport) ^ (sess->proto); + hash &= 0xff; + uint16_t port = (access_id << 14) + (random << 8) + hash; + return htons(port); +} + +//get snat_tx_value, if succeed, has already added to snat_rx_htable +static struct snat_tx_htable_value * snat_tx_value_get(struct snat_handle *handle, const char *user_name, struct mgw_utils_sess *snat_tx_key) +{ + struct ip_mgr_handle *_ip_mgr_handle = handle->_ip_mgr_handle; + int retry_times = 10; + void *logger = handle->logger; + for(int i = 0; i < retry_times; i++) + { + //get candidate ip + uint32_t cand_ip; + int rtn = ip_mgr_snat_cand_ip_get(_ip_mgr_handle, user_name, &cand_ip); + if(rtn < 0) + { + MGW_LOG_ERROR(logger, "Failed at find snat candidate ip, user_name is %s", user_name); + return NULL; + } + //query mrl_ip + uint32_t mrl_ip; + rtn = ip_mgr_mrl_ip_query(_ip_mgr_handle, cand_ip, &mrl_ip); + if(rtn < 0) + { + char cand_ip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(cand_ip, cand_ip_str); + MGW_LOG_ERROR(logger, "mrl ip not found, snat candidate ip is %s", cand_ip_str); + continue; + } + //get candidate port + u_int16_t cand_port = get_candidate_port(handle->access_id, snat_tx_key, cand_ip); + + //try to add to snat_rx_htable + struct mgw_utils_sess *snat_rx_key = ALLOC(struct mgw_utils_sess, 1); + snat_rx_key->sip = snat_tx_key->dip; + snat_rx_key->sport = snat_tx_key->dport; + snat_rx_key->proto = snat_tx_key->proto; + snat_rx_key->dip = cand_ip; + snat_rx_key->dport = cand_port; + struct mgw_utils_sess *snat_rx_value = ALLOC(struct mgw_utils_sess, 1); + snat_rx_value->sip = snat_tx_key->dip; + snat_rx_value->sport = snat_tx_key->dport; + snat_rx_value->proto = snat_tx_key->proto; + snat_rx_value->dip = snat_tx_key->sip; + snat_rx_value->dport = snat_tx_key->sport; + char snat_rx_key_str[MGW_SYMBOL_MAX]; + char snat_rx_value_str[MGW_SYMBOL_MAX]; + mgw_utils_sess_to_str(snat_rx_key, snat_rx_key_str); + mgw_utils_sess_to_str(snat_rx_key, snat_rx_value_str); + rtn = MESA_htable_add(handle->snat_rx_htable, (const unsigned char *)snat_rx_key, sizeof(struct mgw_utils_sess), (void *)snat_rx_value); + FREE(&snat_rx_key); + if(rtn < 0) + { + FREE(&snat_rx_value); + if(rtn != MESA_HTABLE_RET_DUP_ITEM) + { + MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, key is %s, value is %s, rtn is %d", + "snat_rx_htable", snat_rx_key_str, snat_rx_value_str, rtn); + } + continue; + } + else + { + MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, key is %s, value is %s", + "snat_rx_htable", snat_rx_key_str, snat_rx_value_str); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_rx, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); + struct snat_tx_htable_value *snat_tx_value = ALLOC(struct snat_tx_htable_value, 1); + snat_tx_value->sess.sip = snat_tx_key->sip; + snat_tx_value->sess.sport = snat_tx_key->sport; + snat_tx_value->sess.proto = snat_tx_key->proto; + snat_tx_value->sess.dip = cand_ip; + snat_tx_value->sess.dport = cand_port; + snat_tx_value->mrl_ip = mrl_ip; + return snat_tx_value; + } + } + MGW_LOG_ERROR(logger, "snat candidate ip and port conflicts, retry times is %d", retry_times - 1); + return NULL; +} + +int snat_tx_convert(struct snat_handle *handle, char *buff, int len, uint32_t *mrl_ip) +{ + void *logger = handle->logger; + //get session + struct mgw_utils_sess *snat_tx_key = ALLOC(struct mgw_utils_sess, 1); + int rtn = mgw_utils_pkt_sess_parse(buff, len, snat_tx_key); + if(rtn == -1) + { + FREE(&snat_tx_key); + MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len); + return MGW_DROP; + } + char snat_tx_key_str[MGW_SYMBOL_MAX]; + char snat_tx_value_str[MGW_SYMBOL_MAX]; + mgw_utils_sess_to_str(snat_tx_key, snat_tx_key_str); + //query snat_tx_htable + long cb_rtn = -1; + struct snat_tx_htable_value snat_tx_dup_value; + MESA_htable_search_cb(handle->snat_tx_htable, (const unsigned char *)(snat_tx_key), sizeof(struct mgw_utils_sess), snat_tx_htable_query_cb, + (void *)(&snat_tx_dup_value), &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_tx, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_EXISTED) + { + //replace + FREE(&snat_tx_key); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_tx, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + mgw_utils_pkt_sess_replace(buff, len, &(snat_tx_dup_value.sess)); + *mrl_ip = snat_tx_dup_value.mrl_ip; + mgw_utils_sess_to_str(&(snat_tx_dup_value.sess), snat_tx_value_str); + MGW_LOG_INFO(logger, "Succeed at snat_tx_convert: %s ---> %s", snat_tx_key_str, snat_tx_value_str); + return MGW_FORWORD; + } + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_tx, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + //query user_name. user_name not existed: bypass, user_name existed: drop or forward + char dup_user_name[MGW_SYMBOL_MAX]; + cb_rtn = -1; + uint32_t snat_tx_key_sip = snat_tx_key->sip; + char snat_tx_key_sip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(snat_tx_key_sip, snat_tx_key_sip_str); + MESA_htable_search_cb(handle->ip2user_htable, (const unsigned char *)(&snat_tx_key_sip), sizeof(uint32_t), + ip2user_htable_query_cb, (void *)(&dup_user_name), &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_ip2user, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_NOT_EXISTED) + { + mgw_utils_inet_ntoa(snat_tx_key_sip, snat_tx_key_sip_str); + MGW_LOG_INFO(logger, "MESA_htable: key not existed, table is %s, ip is %s", "ip2user", snat_tx_key_sip_str); + FS_operate(g_fs_handle->handle, g_fs_handle->line_ip2user, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + FREE(&snat_tx_key); + return MGW_BYPASS; + } + MGW_LOG_INFO(logger, "MESA_htable: key existed, table is %s, ip is %s", "ip2user", snat_tx_key_sip_str); + FS_operate(g_fs_handle->handle, g_fs_handle->line_ip2user, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + //get snat_tx_value + struct snat_tx_htable_value *snat_tx_value = NULL; + snat_tx_value = snat_tx_value_get(handle, dup_user_name, snat_tx_key); + if(snat_tx_value == NULL) + { + FREE(&snat_tx_key); + MGW_LOG_ERROR(logger, "Failed at snat_tx_convert: session is %s", snat_tx_key_str); + return MGW_DROP; + } + //add to snat_tx_htable + rtn = MESA_htable_add(handle->snat_tx_htable, (const unsigned char *)snat_tx_key, sizeof(struct mgw_utils_sess), (void *)snat_tx_value); + FREE(&snat_tx_key); + if(rtn < 0) + { + if(rtn != MESA_HTABLE_RET_DUP_ITEM) + { + MGW_LOG_ERROR(logger, "MESA_htable: Failed at add, table is %s, key is %s, value is %s, rtn is %d", + "snat_tx_htable", snat_tx_key_str, snat_tx_value_str, rtn); + } + //snat_tx_table and snat_rx_table are Transaction + struct mgw_utils_sess *snat_rx_key = ALLOC(struct mgw_utils_sess, 1); + snat_rx_key->sip = snat_tx_value->sess.dip; + snat_rx_key->sport = snat_tx_value->sess.dport; + snat_rx_key->proto = snat_tx_value->sess.proto; + snat_rx_key->dip = snat_tx_value->sess.sip; + snat_rx_key->dport = snat_tx_value->sess.sport; + char snat_rx_key_str[MGW_SYMBOL_MAX]; + mgw_utils_sess_to_str(snat_rx_key, snat_rx_key_str); + rtn = MESA_htable_del(handle->snat_rx_htable, (const unsigned char *)snat_rx_key, sizeof(struct mgw_utils_sess), NULL); + FREE(&snat_tx_value); + FREE(&snat_rx_key); + if(rtn < 0) + { + MGW_LOG_ERROR(logger, "MESA_htable: Failed at del, table is %s, key is %s, rtn is %s", "snat_rx_htable", snat_rx_key_str, rtn); + } + else + { + MGW_LOG_INFO(logger, "MESA_htable: Succeed at del, table is %s, key is %s", "snat_rx_htable", snat_rx_key_str); + } + return MGW_DROP; + } + else + { + MGW_LOG_INFO(logger, "MESA_htable: Succeed at add, table is %s, key is %s, value is %s", + "snat_tx_htable", snat_tx_key_str, snat_tx_value_str); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_tx, g_fs_handle->cloumn_element_num, FS_OP_ADD, 1); + //replace + mgw_utils_pkt_sess_replace(buff, len, &(snat_tx_value->sess)); + *mrl_ip = snat_tx_value->mrl_ip; + MGW_LOG_INFO(logger, "Succeed at snat_tx_convert: %s ---> %s", snat_tx_key_str, snat_tx_value_str); + return MGW_FORWORD; + } +} + +int snat_rx_convert(struct snat_handle *handle, char *buff, int len) +{ + void *logger = handle->logger; + //get session + struct mgw_utils_sess *snat_rx_key = ALLOC(struct mgw_utils_sess, 1); + int rtn = mgw_utils_pkt_sess_parse(buff, len, snat_rx_key); + if(rtn == -1) + { + FREE(&snat_rx_key); + MGW_LOG_ERROR(logger, "Failed at parse packet, len is %d", len); + return MGW_DROP; + } + char snat_rx_key_str[MGW_SYMBOL_MAX]; + char snat_rx_value_str[MGW_SYMBOL_MAX]; + mgw_utils_sess_to_str(snat_rx_key, snat_rx_key_str); + //query snat_rx_htable + long cb_rtn = -1; + struct mgw_utils_sess snat_rx_dup_value; + MESA_htable_search_cb(handle->snat_rx_htable, (const unsigned char *)(snat_rx_key), sizeof(struct mgw_utils_sess), snat_rx_htable_query_cb, + (void *)(&snat_rx_dup_value), &cb_rtn); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_rx, g_fs_handle->cloumn_query_num, FS_OP_ADD, 1); + if(cb_rtn == MGW_HTABLE_KEY_EXISTED) + { + //replace + FREE(&snat_rx_key); + FS_operate(g_fs_handle->handle, g_fs_handle->line_snat_rx, g_fs_handle->cloumn_cache_hit, FS_OP_ADD, 1); + mgw_utils_pkt_sess_replace(buff, len, &snat_rx_dup_value); + mgw_utils_sess_to_str(&snat_rx_dup_value, snat_rx_value_str); + MGW_LOG_INFO(logger, "Succeed at dnat_rx_convert: %s ---> %s", snat_rx_key_str, snat_rx_value_str); + return MGW_FORWORD; + } + FREE(&snat_rx_key); + FS_operate(g_fs_handle->handle, g_fs_handle->line_dnat_rx, g_fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); + return MGW_BYPASS; +} diff --git a/access/src/udp_server.cpp b/access/src/udp_server.cpp index bcf8547..c3bacc8 100644 --- a/access/src/udp_server.cpp +++ b/access/src/udp_server.cpp @@ -1,7 +1,8 @@ #include "mgw_utils.h" #include "mgw_socket.h" #include "udp_server.h" -#include "nat.h" +#include "snat.h" +#include "dnat.h" #include "mgw_tun.h" void * thread_udp_server(void *args) @@ -9,7 +10,8 @@ void * thread_udp_server(void *args) struct udp_server_args *_args = (struct udp_server_args *)args; void *logger = _args->logger; const char *profile = _args->profile; - struct nat_handle *_nat_handle = _args->_nat_handle; + struct snat_handle *_snat_handle = _args->_snat_handle; + struct dnat_handle *_dnat_handle = _args->_dnat_handle; struct mgw_tun_handle *tun_handle = _args->tun_handle; struct field_stat_handle *fs_handle = _args->fs_handle; FREE(&args); @@ -32,7 +34,7 @@ void * thread_udp_server(void *args) exit(EXIT_FAILURE); } char buff[MGW_PACKET_MAX]; - struct timespec start_time, end_time; + struct timespec start_time; while(1) { //EAGAIN if socket is no-blocking, eg. fcntl() @@ -43,18 +45,40 @@ void * thread_udp_server(void *args) MGW_LOG_ERROR(logger, "mgw_socket: Failed at recv udp data, errno is %d, %s", errno, strerror(errno)); continue; } - FS_operate(fs_handle->handle, fs_handle->field_recv_from_mrl, 0, FS_OP_ADD, 1); + FS_operate(fs_handle->handle, fs_handle->field_rx_from_mrl, 0, FS_OP_ADD, 1); MGW_LOG_INFO(logger, "mgw_socket: Succeed to recv udp data, len is %d", len); - int rtn = nat_dest_convert(_nat_handle, buff, len); - if(rtn == NAT_COVERT_FAILURE) + clock_gettime(CLOCK_MONOTONIC, &start_time); + int rtn = snat_rx_convert(_snat_handle, buff, len); + mgw_utils_fs_latency_cala(fs_handle->handle, start_time, fs_handle->snat_rx_latency); + if(rtn == MGW_DROP) + { + continue; + } + if(rtn == MGW_FORWORD) + { + int rtn = mgw_tun_write(tun_handle, buff, len); + if(rtn >0 && rtn == len) + { + FS_operate(fs_handle->handle, fs_handle->field_tun_write, 0, FS_OP_ADD, 1); + } + continue; + } + //MGW_BYPASS, dnat_rx_convert + clock_gettime(CLOCK_MONOTONIC, &start_time); + rtn = dnat_rx_convert(_dnat_handle, buff, len); + mgw_utils_fs_latency_cala(fs_handle->handle, start_time, fs_handle->dnat_rx_latency); + if(rtn == MGW_DROP) + { + continue; + } + if(rtn == MGW_FORWORD) { + int rtn = mgw_tun_write(tun_handle, buff, len); + if(rtn >0 && rtn == len) + { + FS_operate(fs_handle->handle, fs_handle->field_tun_write, 0, FS_OP_ADD, 1); + } continue; } - //write to tun - mgw_tun_write(tun_handle, buff, len); - FS_operate(fs_handle->handle, fs_handle->field_write_to_tun, 0, FS_OP_ADD, 1); - clock_gettime(CLOCK_MONOTONIC, &end_time); - long long cost_time = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_nsec - start_time.tv_nsec) / 1000; - FS_operate(fs_handle->handle, fs_handle->dnat_latency, 0, FS_OP_SET, cost_time); } }
\ No newline at end of file diff --git a/access/src/vpn_monitor.cpp b/access/src/vpn_monitor.cpp index 2d43193..630ff4a 100644 --- a/access/src/vpn_monitor.cpp +++ b/access/src/vpn_monitor.cpp @@ -37,13 +37,12 @@ static long ip2user_cb_to_del_key(void *data, const uchar *key, uint size, void 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; + return MGW_HTABLE_QUERY_CB_FAILURE; } - FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_element_num, FS_OP_ADD, -1); MGW_LOG_INFO(handle->logger, "MESA_htable: Succeed at del, table is %s, key is %s", "ip2user_htable", _key); } FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_cache_miss, FS_OP_ADD, 1); - return HTABLE_QUERY_CB_SUCCESS; + return MGW_HTABLE_QUERY_CB_SUCCESS; } @@ -191,7 +190,7 @@ static void get_ip2user_by_vpncmd(struct vpn_monitor_handle *handle) long cb_rtn = -1; uint32_t key = inet_addr(ip); MESA_htable_search_cb(handle->ip2user_htable, (const unsigned char *)(&key), sizeof(key), ip2user_cb_to_del_key, (void *)handle, &cb_rtn); - FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_queyr_num, FS_OP_ADD, 1); + FS_operate(fs_handle->handle, fs_handle->line_ip2user, fs_handle->cloumn_query_num, FS_OP_ADD, 1); int rtn = MESA_htable_add(handle->ip2user_htable, (const unsigned char *)(&key), sizeof(key), user_name); if(rtn < 0) { diff --git a/common/include/mgw_utils.h b/common/include/mgw_utils.h index db001f2..3f8e81b 100644 --- a/common/include/mgw_utils.h +++ b/common/include/mgw_utils.h @@ -18,13 +18,13 @@ #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 MGW_HTABLE_QUERY_CB_SUCCESS 0 +#define MGW_HTABLE_QUERY_CB_FAILURE -1 +#define MGW_HTABLE_KEY_EXISTED 0 +#define MGW_HTABLE_KEY_NOT_EXISTED -1 +#define MGW_DROP 0 // something error, drop the packet +#define MGW_BYPASS 1 // give others to handle +#define MGW_FORWORD 2 // for snat: send to mrl, for dnat: send to real server #define likely(expr) __builtin_expect((expr), 1) #define unlikely(expr) __builtin_expect((expr), 0) @@ -50,22 +50,37 @@ MESA_htable_handle mgw_utils_create_htable(const char *profile, const char *sect struct field_stat_handle { screen_stat_handle_t handle; - int field_read_from_tun; - int field_write_to_tun; - int field_recv_from_mrl; - int field_send_to_mrl; - int cloumn_queyr_num; + int field_tun_read; + int field_tun_bypass; + int field_tun_write; + int field_rx_from_mrl; + int field_tx_to_mrl; + int cloumn_query_num; int cloumn_element_num; int cloumn_cache_hit; int cloumn_cache_miss; - int line_snat; - int line_dnat; + int line_snat_rx; + int line_snat_tx; + int line_dnat_rx; + int line_dnat_tx; int line_ip2user; - int line_user_policy; - int line_ip_group; - int line_ip_detail; - int snat_latency; - int dnat_latency; + int line_snat_policy; + int line_dnat_policy; + int line_snat_cand_ip; + int line_mrl_ip; + int snat_rx_latency; + int snat_tx_latency; + int dnat_rx_latency; + int dnat_tx_latency; +}; + +struct mgw_utils_sess +{ + uint32_t sip; + uint16_t sport; + uint32_t dip; + uint16_t dport; + uint8_t proto; }; unsigned int mgw_utils_get_random(unsigned int num); @@ -76,4 +91,12 @@ uint16_t mgw_utils_ip_checksum(const void *buff, size_t hdr_len); uint16_t mgw_utils_tcp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr); -uint16_t mgw_utils_udp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr);
\ No newline at end of file +uint16_t mgw_utils_udp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr); + +int mgw_utils_pkt_sess_parse(const char *buff, int len, struct mgw_utils_sess *sess); + +int mgw_utils_pkt_sess_replace(const char *buff, int len, mgw_utils_sess *sess); + +void mgw_utils_fs_latency_cala(screen_stat_handle_t handle, struct timespec start_time, int field); + +int mgw_utils_sess_to_str(struct mgw_utils_sess *sess, char *sess_str); diff --git a/common/src/mgw_tun.cpp b/common/src/mgw_tun.cpp index b7fe3f7..c17d990 100644 --- a/common/src/mgw_tun.cpp +++ b/common/src/mgw_tun.cpp @@ -64,11 +64,12 @@ int mgw_tun_read(struct mgw_tun_handle *handle, char *buff, size_t len) recv_len = read(handle->fd, buff, len);
if(recv_len < 0)
{
- close(handle->fd);
MGW_LOG_ERROR(logger, "mgw_tun: Failed at read from tun, errno is %d, %s\n", errno, strerror(errno));
- exit(EXIT_FAILURE);
}
- MGW_LOG_INFO(logger, "mgw_tun: Succeed at read from tun, len is %d", recv_len);
+ else
+ {
+ MGW_LOG_INFO(logger, "mgw_tun: Succeed at read from tun, len is %d", recv_len);
+ }
return recv_len;
}
@@ -85,11 +86,12 @@ int mgw_tun_write(struct mgw_tun_handle *handle, char *buff, size_t len) {
if((size_t)send_len < len)
{
- close(handle->fd);
MGW_LOG_ERROR(logger, "mgw_tun: Failed at write to tun completely, need send %d but only send %d", (int)len, send_len);
- exit(EXIT_FAILURE);
+ }
+ else
+ {
+ MGW_LOG_INFO(logger, "mgw_tun: Succeed at write to tun, len is %d", send_len);
}
}
- MGW_LOG_INFO(logger, "mgw_tun: Succeed at write to tun, len is %d", send_len);
return send_len;
}
diff --git a/common/src/mgw_utils.cpp b/common/src/mgw_utils.cpp index 34368c7..d8bd3d4 100644 --- a/common/src/mgw_utils.cpp +++ b/common/src/mgw_utils.cpp @@ -181,4 +181,114 @@ uint16_t mgw_utils_udp_checksum(const void *buff, size_t len, in_addr_t src_addr // Return the one's complement of sum // return ( (uint16_t)(~sum) ); } -
\ No newline at end of file + + int mgw_utils_pkt_sess_parse(const char *buff, int len, struct mgw_utils_sess *sess) +{ + if(len < 20) + { + return -1; + } + struct iphdr *_iphdr = (struct iphdr *)buff; + int iphdr_len = _iphdr->ihl * 4; + sess->sip = _iphdr->saddr; + sess->dip = _iphdr->daddr; + sess->proto = _iphdr->protocol; + switch(sess->proto) + { + case IPPROTO_TCP: + { + if(len < 40) + { + return -1; + } + struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len); + sess->sport = _tcphdr->source; + sess->dport = _tcphdr->dest; + break; + } + case IPPROTO_UDP: + { + if(len < 28) + { + return -1; + } + struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len); + sess->sport = _udphdr->source; + sess->dport = _udphdr->dest; + break; + } + case IPPROTO_ICMP: + { + if(len < 28) + { + return -1; + } + break; + } + default: + return -1; + break; + } + return 0; +} + +int mgw_utils_pkt_sess_replace(const char *buff, int len, mgw_utils_sess *sess) +{ + struct iphdr *_iphdr = (struct iphdr *)buff; + uint16_t tot_len = ntohs(_iphdr->tot_len); + uint16_t iphdr_len = _iphdr->ihl * 4; + _iphdr->saddr = sess->sip; + _iphdr->daddr = sess->dip; + switch(_iphdr->protocol) + { + case IPPROTO_TCP: + { + struct tcphdr *_tcphdr = (struct tcphdr *)(buff + iphdr_len); + uint16_t tcp_len = tot_len - iphdr_len; + _tcphdr->source = sess->sport; + _tcphdr->dest = sess->dport; + _tcphdr->check = 0; + uint16_t tcp_checksum = mgw_utils_tcp_checksum(_tcphdr, tcp_len, _iphdr->saddr, _iphdr->daddr); + _tcphdr->check = tcp_checksum; + break; + } + case IPPROTO_UDP: + { + struct udphdr *_udphdr = (struct udphdr *)(buff + iphdr_len); + uint16_t udp_len = tot_len - iphdr_len; + _udphdr->source = sess->sport; + _udphdr->dest = sess->dport; + _udphdr->check = 0; + uint16_t udp_checksum = mgw_utils_udp_checksum(_udphdr, udp_len, _iphdr->saddr, _iphdr->daddr); + _udphdr->check = udp_checksum; + break; + } + case IPPROTO_ICMP: + break; + default: + break; + } + _iphdr->check = 0; + uint16_t ip_checksum = mgw_utils_ip_checksum(buff, iphdr_len); + _iphdr->check = ip_checksum; + return 0; +} + +void mgw_utils_fs_latency_cala(screen_stat_handle_t handle, struct timespec start_time, int field) +{ + struct timespec end_time; + clock_gettime(CLOCK_MONOTONIC, &end_time); + long long cost_time; + cost_time = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_nsec - start_time.tv_nsec) / 1000; + FS_operate(handle, field, 0, FS_OP_SET, cost_time); +} + +int mgw_utils_sess_to_str(struct mgw_utils_sess *sess, char *sess_str) +{ + char sip_str[MGW_SYMBOL_MAX]; + char dip_str[MGW_SYMBOL_MAX]; + mgw_utils_inet_ntoa(sess->sip, sip_str); + mgw_utils_inet_ntoa(sess->dip, dip_str); + snprintf(sess_str, MGW_SYMBOL_MAX, "<%d, %s:%d, %s:%d>", sess->proto, sip_str, ntohs(sess->sport), dip_str, ntohs(sess->dport)); + return 0; +}
\ No newline at end of file diff --git a/conf/mgw.conf b/conf/mgw.conf index 22b02e8..71d3405 100644 --- a/conf/mgw.conf +++ b/conf/mgw.conf @@ -1,16 +1,17 @@ [global] log_path = /opt/mgw/log/mgw.log log_level = 30 +access_id = 0 -[Maat_cand] +[Maat_snat_policy] table_info_path = /opt/mgw/conf/table_info.conf max_thread_num = 1 Maat_redis_ip = 192.168.11.243 -Maat_redis_port = 6800 -Maat_redis_index = 5 -stat_file_path = /opt/mgw/log/maat_stat.log +Maat_redis_port = 6379 +Maat_redis_index = 6 +stat_file_path = log/maat_stat.log -[Maat_policy] +[Maat_dnat_policy] table_info_path = /opt/mgw/conf/table_info.conf max_thread_num = 1 Maat_redis_ip = 192.168.11.243 @@ -18,6 +19,22 @@ Maat_redis_port = 6379 Maat_redis_index = 6 stat_file_path = log/maat_stat.log +[Maat_snat_cand_ip] +table_info_path = /opt/mgw/conf/table_info.conf +max_thread_num = 1 +Maat_redis_ip = 192.168.11.243 +Maat_redis_port = 6800 +Maat_redis_index = 5 +stat_file_path = /opt/mgw/log/maat_stat.log + +[Maat_mrl_ip] +table_info_path = /opt/mgw/conf/table_info.conf +max_thread_num = 1 +Maat_redis_ip = 192.168.11.243 +Maat_redis_port = 6800 +Maat_redis_index = 5 +stat_file_path = /opt/mgw/log/maat_stat.log + [field_stat] stat_path = /opt/mgw/fs2_mgw.status @@ -34,8 +51,16 @@ port = 23456 ip = 192.168.11.137 port = 33456 +[snat_tx_htable] +mho_screen_print_ctrl = 0 +mho_thread_safe = 1 +mho_mutex_num = 160 +mho_hash_slot_size = 160000 +mho_hash_max_element_num = 640000 +mho_expire_time = 90 +mho_eliminate_type = LRU -[snat_htable] +[snat_rx_htable] mho_screen_print_ctrl = 0 mho_thread_safe = 1 mho_mutex_num = 160 @@ -44,7 +69,16 @@ mho_hash_max_element_num = 640000 mho_expire_time = 90 mho_eliminate_type = LRU -[dnat_htable] +[dnat_tx_htable] +mho_screen_print_ctrl = 0 +mho_thread_safe = 1 +mho_mutex_num = 160 +mho_hash_slot_size = 160000 +mho_hash_max_element_num = 640000 +mho_expire_time = 90 +mho_eliminate_type = LRU + +[dnat_rx_htable] mho_screen_print_ctrl = 0 mho_thread_safe = 1 mho_mutex_num = 160 @@ -62,7 +96,7 @@ mho_hash_max_element_num = 64000 mho_expire_time = 0 mho_eliminate_type = LRU -[user_policy_htable] +[snat_policy_htable] mho_screen_print_ctrl = 0 mho_thread_safe = 1 mho_mutex_num = 16 @@ -71,21 +105,21 @@ mho_hash_max_element_num = 64000 mho_expire_time = 0 mho_eliminate_type = LRU -[cand_ip_group_htable] +[dnat_policy_htable] mho_screen_print_ctrl = 0 mho_thread_safe = 1 mho_mutex_num = 16 -mho_hash_slot_size = 1600 -mho_hash_max_element_num = 6400 +mho_hash_slot_size = 16000 +mho_hash_max_element_num = 64000 mho_expire_time = 0 mho_eliminate_type = LRU -[cand_ip_detail_htable] +[snat_cand_ip_htable] mho_screen_print_ctrl = 0 mho_thread_safe = 1 mho_mutex_num = 16 -mho_hash_slot_size = 16000 -mho_hash_max_element_num = 64000 +mho_hash_slot_size = 1600 +mho_hash_max_element_num = 6400 mho_expire_time = 0 mho_eliminate_type = LRU diff --git a/conf/table_info.conf b/conf/table_info.conf index 573afba..dbed545 100644 --- a/conf/table_info.conf +++ b/conf/table_info.conf @@ -16,4 +16,7 @@ #For expr/expr_plus Table #id name type src_charset dst_charset do_merge cross_cache quick_mode 0 IR_SNAT_POLICY plugin 6 -- -1 IR_CANDIDATE_IP plugin 19 -- +1 IR_DNAT_POLICY plugin 11 -- +2 IR_MRL_IP_INFO plugin 5 -- +3 IR_CANDIDATE_IP plugin 6 -- + |
