From 94e8c6184dc3f2318065aba2fb51ef5f3ad8dc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=94=E4=B8=80=E9=B8=A3?= Date: Wed, 4 Sep 2019 18:58:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90polling=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=94=B9=E9=80=A0=E5=92=8C=E9=87=8D=E5=A4=8D=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/CMakeLists.txt | 5 + common/include/kni_utils.h | 50 +- common/src/kni_utils.cpp | 35 +- common/test/test_dabloom.cpp | 10 + conf/kni.conf | 52 +- conf/maat/maat_tableinfo.conf | 2 +- conf/sapp/kni/kni.inf | 6 +- entry/CMakeLists.txt | 2 +- entry/include/kni_maat.h | 2 +- entry/src/kni_entry.cpp | 1250 +++++++++++++----------- entry/src/kni_maat.cpp | 8 +- entry/src/kni_tap.cpp | 74 ++ script/run.sh | 17 +- vendor/CMakeLists.txt | 14 + vendor/dablooms-v1.0.0-20190904.tar.gz | Bin 0 -> 19798 bytes 15 files changed, 886 insertions(+), 641 deletions(-) create mode 100644 common/test/test_dabloom.cpp create mode 100644 entry/src/kni_tap.cpp create mode 100644 vendor/dablooms-v1.0.0-20190904.tar.gz diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 70def4d..899cc1e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -11,3 +11,8 @@ target_link_libraries(test_cmsg PRIVATE common) add_executable(test_uuid test/test_uuid.cpp) target_include_directories(test_uuid PRIVATE include) target_link_libraries(test_uuid PRIVATE uuid common) + +### test_dabloom +add_executable(test_dabloom test/test_dabloom.cpp) +target_include_directories(test_dabloom PRIVATE include) +target_link_libraries(test_dabloom PRIVATE dabloom common) diff --git a/common/include/kni_utils.h b/common/include/kni_utils.h index a38b1a2..83f7ea7 100644 --- a/common/include/kni_utils.h +++ b/common/include/kni_utils.h @@ -20,6 +20,7 @@ #define KNI_PATH_MAX 256 #define KNI_SYMBOL_MAX 64 #define KNI_DOMAIN_MAX 256 +#define KNI_ADDR_MAX 128 #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) @@ -57,19 +58,26 @@ struct kni_tcpopt_info{ uint16_t mss; uint8_t wscale_set; uint8_t wscale; - uint8_t ts; + uint8_t ts_set; uint8_t sack; + uint32_t ts_value; }; //field_stat -#define KNI_FIELD_MAX 64 +#define KNI_FS_FIELD_MAX 64 +#define KNI_FS_COLUMN_MAX 256 +#define KNI_FS_LINE_MAX 256 enum kni_field{ KNI_FIELD_INTCP_STM, KNI_FIELD_BYP_STM, - KNI_FIELD_POLICY_BYP, - KNI_FIELD_PME_NEW_FAIL, - KNI_FIELD_NO_TFE, + KNI_FIELD_BYP_STM_POLICY, + KNI_FIELD_BYP_STM_PME_NEW_FAIL, + KNI_FIELD_BYP_STM_NO_TFE, + KNI_FIELD_BYP_STM_ERR, + KNI_FIELD_BYP_STM_DUP_TFC, KNI_FIELD_STATE_UNKNOWN, + KNI_FIELD_DUP_TFC_STM, + //stream error KNI_FIELD_STM_ERR, KNI_FIELD_NO_SYN, KNI_FIELD_SINGLE_DIR, @@ -77,10 +85,9 @@ enum kni_field{ KNI_FIELD_NO_SA, KNI_FIELD_ACTION_INVALID, KNI_FIELD_NO_DATA, - KNI_FIELD_IPV4HDR_PARSE_FAIL, - KNI_FIELD_IPV6HDR_PARSE_FAIL, - KNI_FIELD_KA_ADD_FAIL, + KNI_FIELD_IPHDR_PARSE_FAIL, KNI_FIELD_EXCEED_MTU, + KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL, KNI_FIELD_SENDTO_TFE_FAIL, //others KNI_FIELD_NULL_PKT, @@ -92,27 +99,43 @@ enum kni_field{ KNI_FIELD_SENDLOG_FAIL, KNI_FIELD_PME_NEW_SUCC, KNI_FIELD_PME_FREE, + KNI_FIELD_IPV4HDR_PARSE_FAIL, + KNI_FIELD_IPV6HDR_PARSE_FAIL, KNI_FIELD_ID2PME_ADD_SUCC, KNI_FIELD_ID2PME_ADD_FAIL, KNI_FIELD_ID2PME_DEL_SUCC, KNI_FIELD_ID2PME_DEL_FAIL, - KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC, - KNI_FIELD_KEEPALIVE_REPLAY_DEL_SUCC, - KNI_FIELD_KEEPALIVE_REPLAY_DEL_FAIL, + KNI_FIELD_TUPLE2STM_ADD_SUCC, + KNI_FIELD_TUPLE2STM_ADD_FAIL, + KNI_FIELD_TUPLE2STM_DEL_SUCC, + KNI_FIELD_TUPLE2STM_DEL_FAIL, KNI_FIELD_KNI_INTCP_BYTES, KNI_FIELD_TFE_INTCP_BYTES, KNI_FIELD_KNI_INTCP_STM, KNI_FIELD_TFE_INTCP_STM, + KNI_FIELD_TUPLE2STM_SEARCH_SUCC, + KNI_FIELD_TUPLE2STM_SEARCH_FAIL, + KNI_FIELD_SAPP_INJECT_SUCC, + KNI_FIELD_SAPP_INJECT_FAIL, + KNI_FIELD_BLOOM_SEARCH_SUCC, + KNI_FIELD_BLOOM_SEARCH_FAIL, + KNI_FIELD_BLOOM_ADD_SUCC, + KNI_FIELD_BLOOM_ADD_FAIL, //KNI_FIELD_TFE_STATUS_BASE must be last KNI_FIELD_TFE_STATUS_BASE, }; struct kni_field_stat_handle{ screen_stat_handle_t handle; - int fields[KNI_FIELD_MAX]; + int fields[KNI_FS_FIELD_MAX]; + int column_ids[KNI_FS_COLUMN_MAX]; + int line_ids[KNI_FS_LINE_MAX]; + int column_cnt; + int line_cnt; }; struct pkt_info{ + addr_type_t addr_type; union{ struct iphdr *v4; struct ip6_hdr *v6; @@ -135,7 +158,8 @@ enum kni_ipv6hdr_parse_error{ KNI_IPV6HDR_PARSE_ERROR_INVALID_TYPE = -3, }; -int kni_stream_addr_trans(const struct layer_addr *addr, addr_type_t addr_type, char *output, int len); +int kni_addr_trans_v4(struct stream_tuple4_v4 *tuple4, char *output, int len); +int kni_addr_trans_v6(struct stream_tuple4_v6 *tuple4, char *output, int len); uint16_t kni_ip_checksum(const void *buf, size_t hdr_len); uint16_t kni_tcp_checksum(const void *_buf, size_t len, in_addr_t src_addr, in_addr_t dest_addr); uint16_t kni_tcp_checksum_v6(const void *_buf, size_t len, struct in6_addr src_addr, struct in6_addr dest_addr); diff --git a/common/src/kni_utils.cpp b/common/src/kni_utils.cpp index 52f8295..cafaa73 100644 --- a/common/src/kni_utils.cpp +++ b/common/src/kni_utils.cpp @@ -3,22 +3,24 @@ #include #include -int kni_stream_addr_trans(const struct layer_addr *addr, addr_type_t addr_type, char *output, int len){ +int kni_addr_trans_v4(struct stream_tuple4_v4 *tuple4, char *output, int len){ + char saddr[INET_ADDRSTRLEN]; + char daddr[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(tuple4->saddr), saddr, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(tuple4->daddr), daddr, INET_ADDRSTRLEN); + uint16_t source = ntohs(tuple4->source); + uint16_t dest = ntohs(tuple4->dest); + snprintf(output, len, "%s:%d -> %s:%d", saddr, source, daddr, dest); + return 0; +} + +int kni_addr_trans_v6(struct stream_tuple4_v6 *tuple4, char *output, int len){ char saddr[INET6_ADDRSTRLEN]; char daddr[INET6_ADDRSTRLEN]; - uint16_t source, dest; - if(addr_type == ADDR_TYPE_IPV6){ - inet_ntop(AF_INET6, &(addr->tuple4_v6->saddr), saddr, INET6_ADDRSTRLEN); - inet_ntop(AF_INET6, &(addr->tuple4_v6->daddr), daddr, INET6_ADDRSTRLEN); - source = ntohs(addr->tuple4_v6->source); - dest = ntohs(addr->tuple4_v6->dest); - } - else{ - inet_ntop(AF_INET, &(addr->tuple4_v4->saddr), saddr, INET6_ADDRSTRLEN); - inet_ntop(AF_INET, &(addr->tuple4_v4->daddr), daddr, INET6_ADDRSTRLEN); - source = ntohs(addr->tuple4_v4->source); - dest = ntohs(addr->tuple4_v4->dest); - } + inet_ntop(AF_INET6, tuple4->saddr, saddr, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, tuple4->daddr, daddr, INET6_ADDRSTRLEN); + uint16_t source = ntohs(tuple4->source); + uint16_t dest = ntohs(tuple4->dest); snprintf(output, len, "%s:%d -> %s:%d", saddr, source, daddr, dest); return 0; } @@ -195,7 +197,8 @@ struct kni_tcpopt_info* kni_get_tcpopt(struct tcphdr* tcphdr,int tcphdr_len){ break; case TCPOPT_TIMESTAMP: if ((opsize == TCPOLEN_TIMESTAMP)){ - tcpopt->ts = 1; + tcpopt->ts_set = 1; + tcpopt->ts_value = *(uint32_t*)ptr; } break; case TCPOPT_SACK_PERMITTED: @@ -333,6 +336,7 @@ int kni_ipv4_header_parse(const void *a_packet, struct pkt_info *pktinfo){ if(a_packet == NULL){ return KNI_IPV4HDR_PARSE_ERROR_NULL_PACKET; } + pktinfo->addr_type = ADDR_TYPE_IPV4; pktinfo->iphdr.v4 = (struct iphdr*)a_packet; pktinfo->iphdr_len = pktinfo->iphdr.v4->ihl * 4; pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v4->tot_len); @@ -347,6 +351,7 @@ int kni_ipv6_header_parse(const void *a_packet, struct pkt_info *pktinfo){ if(a_packet == NULL){ return KNI_IPV6HDR_PARSE_ERROR_NULL_PACKET; } + pktinfo->addr_type = ADDR_TYPE_IPV6; pktinfo->iphdr.v6 = (struct ip6_hdr*)a_packet; pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr); uint8_t next_hdr_type = pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_nxt; diff --git a/common/test/test_dabloom.cpp b/common/test/test_dabloom.cpp new file mode 100644 index 0000000..67bd7d1 --- /dev/null +++ b/common/test/test_dabloom.cpp @@ -0,0 +1,10 @@ +#include +#include +extern "C" { + #include "dablooms.h" +} + + +int main(int argc, char *argv[]){ + +} \ No newline at end of file diff --git a/conf/kni.conf b/conf/kni.conf index cd12202..48df930 100644 --- a/conf/kni.conf +++ b/conf/kni.conf @@ -2,36 +2,33 @@ log_path = ./log/kni/kni.log log_level = 10 tfe_node_count = 3 -tfe_data_recv_thread_num = 8 -manage_eth = eth0 -#keepalive_replay: window update replay -keepalive_replay_switch = 1 +manage_eth = enp7s0 [tfe0] enabled = 1 mac_addr = fe:65:b7:03:50:bd -dev_eth_symbol = eth7 -ip_addr = 192.168.10.38 +dev_eth_symbol = ens1f5 +ip_addr = 192.168.100.2 [tfe1] enabled = 1 mac_addr = fe:65:b7:03:50:bd -dev_eth_symbol = eth8 -ip_addr = 192.168.10.39 +dev_eth_symbol = ens1f6 +ip_addr = 192.168.100.3 [tfe2] enabled = 1 mac_addr = fe:65:b7:03:50:bd -dev_eth_symbol = eth9 -ip_addr = 192.168.10.40 +dev_eth_symbol = ens1f7 +ip_addr = 192.168.100.4 [tfe_cmsg_receiver] -listen_eth = eth0 +listen_eth = ens1.100 listen_port = 2475 [watch_dog] switch = 1 -listen_eth = eth0 +listen_eth = ens1.100 listen_port = 2476 keepalive_idle = 2 keepalive_intvl = 1 @@ -39,12 +36,12 @@ keepalive_cnt = 3 [maat] #readconf_mode: 0 = iris, 1 = json, 2 = redis -readconf_mode = 1 -tableinfo_path = ./conf/kni/maat_tableinfo.conf -maatjson_path = ./conf/kni/maat_test.json -redis_ip = 192.168.10.120 -redis_port = 6390 -redis_index = 4 +readconf_mode = 2 +tableinfo_path = ./etc/kni/maat_tableinfo.conf +maatjson_path = ./etc/kni/maat_test.json +redis_ip = 192.168.10.31 +redis_port = 6379 +redis_index = 0 tablename_intercept_ip = PXY_INTERCEPT_IP tablename_intercept_domain = PXY_INTERCEPT_DOMAIN #default_action: 0x80 = bypass, 0x02 = intercept @@ -53,11 +50,11 @@ default_action = 128 [send_logger] switch = 0 kafka_topic = SESSION-RECORD-LOG -kafka_brokerlist = 192.168.10.119:9092,192.168.10.122:9092,192.168.10.123:9092 +#kafka_brokerlist = 192.168.10.119:9092,192.168.10.122:9092,192.168.10.123:9092 +kafka_brokerlist = 192.168.10.52:9092 [marsio] appsym = knifw -dev_vxlan_symbol = vxlan_user src_mac_addr = 00:0e:c6:d6:72:c1 [kafka] @@ -65,6 +62,14 @@ queue.buffering.max.messages = 1000000 topic.metadata.refresh.interval.ms = 600000 security.protocol = MG +#128:bypass, 2: intercept +[dup_traffic] +switch = 0 +action = 2 +capacity = 1000000 +error_rate = 0.05 +expiry_time = 30 + [traceid2pme_htable] mho_screen_print_ctrl = 0 mho_thread_safe = 1 @@ -74,15 +79,12 @@ mho_hash_max_element_num = 640000 mho_expire_time = 30 mho_eliminate_type = LRU -[keepalive_replay_htable] +[tuple2stream_htable] mho_screen_print_ctrl = 0 -mho_thread_safe = 1 +mho_thread_safe = 0 mho_mutex_num = 160 mho_hash_slot_size = 160000 mho_hash_max_element_num = 640000 -#must be 0 -mho_expire_time = 0 -mho_eliminate_type = LRU [field_stat] stat_path = ./fs2_kni.status \ No newline at end of file diff --git a/conf/maat/maat_tableinfo.conf b/conf/maat/maat_tableinfo.conf index 43455f8..e67ea3c 100644 --- a/conf/maat/maat_tableinfo.conf +++ b/conf/maat/maat_tableinfo.conf @@ -5,4 +5,4 @@ 3 TSG_OBJ_IP_ADDR ip_plus -- 4 PXY_INTERCEPT_DOMAIN expr utf8 utf8 yes 0 4 TSG_OBJ_FQDN expr utf8 utf8 yes 0 -5 COMPILE_ALIAS compile escape -- +5 COMPILE_ALIAS compile escape -- \ No newline at end of file diff --git a/conf/sapp/kni/kni.inf b/conf/sapp/kni/kni.inf index 1b0b72e..6ed255d 100644 --- a/conf/sapp/kni/kni.inf +++ b/conf/sapp/kni/kni.inf @@ -10,4 +10,8 @@ FUNC_NAME = kni_tcpall_entry [HTTP] FUNC_FLAG = HTTP_HOST -FUNC_NAME = kni_http_entry \ No newline at end of file +FUNC_NAME = kni_http_entry + +[POLLING] +FUNC_FLAG=ALL +FUNC_NAME=kni_polling_all_entry \ No newline at end of file diff --git a/entry/CMakeLists.txt b/entry/CMakeLists.txt index 846543e..4916c99 100644 --- a/entry/CMakeLists.txt +++ b/entry/CMakeLists.txt @@ -1,3 +1,3 @@ add_library(kni SHARED src/kni_entry.cpp src/kni_maat.cpp src/kni_send_logger.cpp src/tfe_mgr.cpp) target_include_directories(kni PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) -target_link_libraries(kni common MESA_prof_load MESA_htable MESA_field_stat maatframe marsio uuid cjson rdkafka) \ No newline at end of file +target_link_libraries(kni common MESA_prof_load MESA_htable MESA_field_stat maatframe marsio uuid cjson rdkafka dabloom) \ No newline at end of file diff --git a/entry/include/kni_maat.h b/entry/include/kni_maat.h index e9846bb..7569ff7 100644 --- a/entry/include/kni_maat.h +++ b/entry/include/kni_maat.h @@ -25,7 +25,7 @@ enum kni_action{ KNI_ACTION_BYPASS = 0x80 }; -struct kni_maat_handle* kni_maat_init(const char* profile, void *logger); +struct kni_maat_handle* kni_maat_init(const char* profile, void *logger, int thread_count); void kni_maat_destroy(struct kni_maat_handle *handle); enum kni_action intercept_policy_scan(struct kni_maat_handle* handle, struct ipaddr *addr, char *domain, int domain_len, int thread_seq, int *policy_id, int *do_log, int *is_hit_policy); diff --git a/entry/src/kni_entry.cpp b/entry/src/kni_entry.cpp index 593e223..161bc95 100644 --- a/entry/src/kni_entry.cpp +++ b/entry/src/kni_entry.cpp @@ -1,17 +1,27 @@ +/* +intercept: destroy_pme + send_log + del traceid2pem + del tuple2stream + +bypass: drome: pme_new_fail: destroy_pme + no_tfe: destroy_pme + stream_error: destroy_pme + send_log + + giveme: policy: destroy_pme + send_log + dup_traffic: destroy_pme + send_log +*/ + #include "kni_utils.h" #include "ssl_utils.h" #include "marsio.h" #include "kni_maat.h" #include "MESA/http.h" +#include "MESA/stream_inc/sapp_inject.h" #include "kni_cmsg.h" #include "uuid/uuid.h" #include "cjson/cJSON.h" #include "kni_send_logger.h" #include #include "tfe_mgr.h" - -extern int g_iThreadNum; - +#include "dablooms.h" struct kni_handle *g_kni_handle = NULL; struct kni_field_stat_handle *g_kni_fs_handle = NULL; @@ -36,11 +46,10 @@ enum stream_error{ STREAM_ERROR_NO_SYN_ACK = -4, STREAM_ERROR_INVALID_ACTION = -5, STREAM_ERROR_NO_DATA = -6, - STREAM_ERROR_IPV4HDR_PARSE_FAIL = -7, - STREAM_ERROR_IPV6HDR_PARSE_FAIL = -8, - STREAM_ERROR_KA_REPLAY_ADD_FAIL = -9, - STREAM_ERROR_EXCEED_MTU = -10, - STREAM_ERROR_SENDTO_TFE_FAIL = -11, + STREAM_ERROR_IPHDR_PARSE_FAIL = -7, + STREAM_ERROR_EXCEED_MTU = -8, + STREAM_ERROR_SENDTO_TFE_FAIL = -9, + STREAM_ERROR_TUPLE2STM_ADD_FAIL = -10, }; struct http_project{ @@ -48,6 +57,19 @@ struct http_project{ char host[KNI_DOMAIN_MAX]; }; +//memset 0 +struct dup_traffic_dabloom_key{ + union{ + struct stream_tuple4_v4 v4; + struct stream_tuple4_v6 v6; + }addr; + uint16_t ipid; + uint8_t ttl; + uint32_t seq; + uint32_t ack_seq; + uint32_t timestamp; +}; + struct pme_info{ addr_type_t addr_type; int protocol; @@ -92,6 +114,13 @@ struct pme_info{ char ssl_client_side_version[KNI_SYMBOL_MAX]; uint64_t ssl_cert_verify; char ssl_error[KNI_STRING_MAX]; + + //for dup traffic detect + int has_dup_traffic; + int has_dup_syn; + int has_dup_syn_ack; + struct dup_traffic_dabloom_key *syn_packet; + struct dup_traffic_dabloom_key *syn_ack_packet; }; struct wrapped_packet{ @@ -115,8 +144,6 @@ struct kni_marsio_handle{ struct mr_instance *instance; int tfe_enabled_node_count; struct tfe_enabled_node tfe_enabled_nodes[TFE_COUNT_MAX]; - struct mr_vdev *dev_vxlan_handler; - struct mr_sendpath *dev_vxlan_sendpath; char src_mac_addr[6]; }; @@ -126,30 +153,38 @@ struct protocol_identify_result{ int domain_len; }; - -struct thread_tfe_data_receiver_args{ - void *logger; - struct kni_marsio_handle *marsio_handle; - int thread_seq; -}; - struct thread_tfe_cmsg_receiver_args{ void *logger; char profile[KNI_SYMBOL_MAX]; }; + +struct per_thread_handle{ + MESA_htable_handle tuple2stream_htable; + struct expiry_dablooms_handle *dabloom_handle; +}; + +struct tuple2stream_htable_value{ + struct streaminfo *stream; + struct pme_info *pmeinfo; + int route_dir; + int reversed; +}; + + struct kni_handle{ int http_project_id; struct kni_marsio_handle *marsio_handle; struct kni_maat_handle *maat_handle; struct kni_send_logger *send_logger; MESA_htable_handle traceid2pme_htable; - MESA_htable_handle keepalive_replay_htable; - int tfe_data_recv_thread_num; + struct per_thread_handle *threads_handle; uint32_t local_ipv4; - int keepalive_replay_switch; void *local_logger; struct tfe_mgr *_tfe_mgr; + int thread_count; + int dup_traffic_switch; + int dup_traffic_action; }; struct traceid2pme_search_cb_args{ @@ -157,21 +192,6 @@ struct traceid2pme_search_cb_args{ void *logger; }; -struct keepalive_replay_htable_value{ - int has_replayed; - uint32_t first_data_len; - uint16_t window; -}; - -struct keepalive_replay_search_cb_args{ - marsio_buff_t *rx_buff; - struct kni_marsio_handle *marsio_handle; - void *raw_packet; - addr_type_t addr_type; - int tfe_id; - int thread_seq; -}; - static char* stream_errmsg_get(enum stream_error _errno){ switch(_errno){ case STREAM_ERROR_PENDING_NO_SYN: @@ -186,21 +206,47 @@ static char* stream_errmsg_get(enum stream_error _errno){ return (char*)"invalid aciton"; case STREAM_ERROR_NO_DATA: return (char*)"no data"; - case STREAM_ERROR_IPV4HDR_PARSE_FAIL: - return (char*)"ipv4 header parse fail"; - case STREAM_ERROR_IPV6HDR_PARSE_FAIL: - return (char*)"ipv6 header parse fail"; - case STREAM_ERROR_KA_REPLAY_ADD_FAIL: - return (char*)"keepalive_replay_add_fail"; + case STREAM_ERROR_IPHDR_PARSE_FAIL: + return (char*)"ip header parse fail"; case STREAM_ERROR_EXCEED_MTU: return (char*)"exceed mtu(1500)"; case STREAM_ERROR_SENDTO_TFE_FAIL: return (char*)"sendto_tfe_fail"; + case STREAM_ERROR_TUPLE2STM_ADD_FAIL: + return (char*)"tuple2stm_add_fail"; default: return (char*)"unknown error"; } } +static int dup_traffic_dabloom_key_get(struct pkt_info *pktinfo, struct dup_traffic_dabloom_key *key){ + //ipv6 + struct tcphdr *tcphdr = pktinfo->tcphdr; + key->seq = tcphdr->seq; + key->ack_seq = tcphdr->ack_seq; + struct kni_tcpopt_info* tcpopt = kni_get_tcpopt(tcphdr, pktinfo->tcphdr_len); + key->timestamp = tcpopt->ts_value; + FREE(&tcpopt); + if(pktinfo->addr_type == ADDR_TYPE_IPV6){ + struct ip6_hdr *iphdr = pktinfo->iphdr.v6; + memcpy(key->addr.v6.saddr, &(iphdr->ip6_src), sizeof(key->addr.v6.saddr)); + memcpy(key->addr.v6.daddr, &(iphdr->ip6_dst), sizeof(key->addr.v6.daddr)); + key->addr.v6.source = tcphdr->source; + key->addr.v6.dest = tcphdr->dest; + } + //ipv4 + else{ + struct iphdr *iphdr = pktinfo->iphdr.v4; + key->addr.v4.saddr = iphdr->saddr; + key->addr.v4.daddr = iphdr->daddr; + key->addr.v4.source = tcphdr->source; + key->addr.v4.dest = tcphdr->dest; + key->ttl = iphdr->ttl; + key->ipid = iphdr->id; + } + return 0; +} + static void pme_info_destroy(void *data){ struct pme_info *pmeinfo = (struct pme_info *)data; void *logger = g_kni_handle->local_logger; @@ -218,11 +264,15 @@ static void pme_info_destroy(void *data){ pmeinfo->addr=NULL; //free lock pthread_mutex_destroy(&(pmeinfo->lock)); + //free syn/syn_ack + FREE(&(pmeinfo->syn_packet)); + FREE(&(pmeinfo->syn_ack_packet)); + FREE(&pmeinfo); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_FREE], 0, FS_OP_ADD, 1); } else{ - KNI_LOG_ERROR(logger, "Failed at pme_info_destroy, pmeinfo is null"); + KNI_LOG_ERROR(logger, "Failed at pme_info_destroy, pmeinfo = null"); } } @@ -235,16 +285,20 @@ static struct pme_info* pme_info_new(const struct streaminfo *stream, int thread uuid_unparse(uu, pmeinfo->stream_traceid); pmeinfo->addr = layer_addr_dup(&(stream->addr)); clock_gettime(CLOCK_REALTIME, &(pmeinfo->start_time)); - char stream_addr[KNI_SYMBOL_MAX] = ""; + char stream_addr[KNI_ADDR_MAX] = ""; //init pme_lock int ret = pthread_mutex_init(&(pmeinfo->lock), NULL); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at init pthread mutex, stream_traceid is %s", pmeinfo->stream_traceid); + KNI_LOG_ERROR(logger, "Failed at init pthread mutex, stream_traceid = %s", pmeinfo->stream_traceid); goto error_out; } - kni_stream_addr_trans(&(stream->addr), pmeinfo->addr_type, stream_addr, sizeof(stream_addr)); - KNI_LOG_INFO(logger, "stream addr is %s, stream traceid is %s", stream_addr, pmeinfo->stream_traceid); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TOT_STM], 0, FS_OP_ADD, 1); + if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ + kni_addr_trans_v6(stream->addr.tuple4_v6, stream_addr, sizeof(stream_addr)); + } + else{ + kni_addr_trans_v4(stream->addr.tuple4_v4, stream_addr, sizeof(stream_addr)); + } + KNI_LOG_INFO(logger, "stream addr = %s, stream traceid = %s", stream_addr, pmeinfo->stream_traceid); return pmeinfo; error_out: @@ -350,20 +404,27 @@ static int log_generate(struct pme_info *pmeinfo, void *local_logger){ cJSON_AddNumberToObject(log_obj, "c2s_byte_num", pmeinfo->server_bytes); //s2c_byte_num cJSON_AddNumberToObject(log_obj, "s2c_byte_num", pmeinfo->client_bytes); + //dup_traffic + cJSON_AddNumberToObject(log_obj, "has_dup_traffic", pmeinfo->has_dup_traffic); + //stream_error + if(pmeinfo->error < 0){ + char *stream_errmsg = stream_errmsg_get(pmeinfo->error); + cJSON_AddStringToObject(log_obj, "stream_error", stream_errmsg); + } int ret = -1; char *log_msg = cJSON_PrintUnformatted(log_obj); cJSON_Delete(log_obj); if(log_msg == NULL){ - KNI_LOG_ERROR(local_logger, "Failed at cJSON_Print, stream_treaceid is %s", pmeinfo->stream_traceid); + KNI_LOG_ERROR(local_logger, "Failed at cJSON_Print, stream_treaceid = %s", pmeinfo->stream_traceid); goto error_out; } //local log - KNI_LOG_DEBUG(local_logger, "log_msg is %s\n", log_msg); + KNI_LOG_DEBUG(local_logger, "log_msg = %s\n", log_msg); //sendto kafka ret = kni_send_logger_sendlog(g_kni_handle->send_logger, log_msg, strlen(log_msg)); if(ret < 0){ FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDLOG_FAIL], 0, FS_OP_ADD, 1); - KNI_LOG_ERROR(local_logger, "Failed at sendlog_to_kafka, ret is %d, strem_traceid is %s", + KNI_LOG_ERROR(local_logger, "Failed at sendlog_to_kafka, ret = %d, strem_traceid = %s", ret, pmeinfo->stream_traceid); goto error_out; } @@ -377,80 +438,18 @@ error_out: } return -1; } - -static void keepalive_replay_htable_del(struct pme_info *pmeinfo){ - void *logger = g_kni_handle->local_logger; - int key_size = 0, ret; - char stream_addr[KNI_SYMBOL_MAX] = ""; - kni_stream_addr_trans((const layer_addr*)(pmeinfo->addr), pmeinfo->addr_type, stream_addr, sizeof(stream_addr)); - //c2s - struct stream_tuple4_v4 *c2s_key_v4 = NULL; - struct stream_tuple4_v6 *c2s_key_v6 = NULL; - key_size = 0; - if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ - c2s_key_v6 = pmeinfo->addr->tuple4_v6; - key_size = sizeof(struct stream_tuple4_v6); - ret = MESA_htable_del(g_kni_handle->keepalive_replay_htable, (const unsigned char*)c2s_key_v6, key_size, NULL); - } - else{ - c2s_key_v4 = pmeinfo->addr->tuple4_v4; - key_size = sizeof(struct stream_tuple4_v4); - ret = MESA_htable_del(g_kni_handle->keepalive_replay_htable, (const unsigned char*)c2s_key_v4, key_size, NULL); - } - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table is %s, stream addr is %s, dir is c2s, ret is %d", - "keepalive_replay_htable", stream_addr, ret); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_DEL_FAIL], 0, FS_OP_ADD, 1); - } - else{ - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_DEL_SUCC], 0, FS_OP_ADD, 1); - //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at del, table is %s, stream addr is %s, dir is c2s", - // "keepalive_replay_htable", stream_addr); - } - //s2c - if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ - struct stream_tuple4_v6 s2c_key_v6; - memcpy(s2c_key_v6.saddr, c2s_key_v6->daddr, sizeof(s2c_key_v6.saddr)); - memcpy(s2c_key_v6.daddr, c2s_key_v6->saddr, sizeof(s2c_key_v6.daddr)); - s2c_key_v6.source = c2s_key_v6->dest; - s2c_key_v6.dest = c2s_key_v6->source; - key_size = sizeof(struct stream_tuple4_v6); - ret = MESA_htable_del(g_kni_handle->keepalive_replay_htable, (const unsigned char*)&s2c_key_v6, - key_size, NULL); - } - else{ - struct stream_tuple4_v4 s2c_key_v4; - s2c_key_v4.saddr = c2s_key_v4->daddr; - s2c_key_v4.daddr = c2s_key_v4->saddr; - s2c_key_v4.source = c2s_key_v4->dest; - s2c_key_v4.dest = c2s_key_v4->source; - key_size = sizeof(struct stream_tuple4_v4); - ret = MESA_htable_del(g_kni_handle->keepalive_replay_htable, (const unsigned char*)&s2c_key_v4, - key_size, NULL); - } - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table is %s, stream addr is %s, dir is s2c, ret is %d", - "keepalive_replay_htable", stream_addr, ret); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_DEL_FAIL], 0, FS_OP_ADD, 1); - } - else{ - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_DEL_SUCC], 0, FS_OP_ADD, 1); - //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at del, table is %s, stream addr is %s, dir is s2c", - // "keepalive_replay_htable", stream_addr); - } -} -static void stream_destroy(struct pme_info *pmeinfo){ +static void stream_destroy(struct pme_info *pmeinfo, int do_log){ //sendlog void *logger = g_kni_handle->local_logger; int ret; - if(pmeinfo->do_log == 1){ + if(do_log == 1){ ret = log_generate(pmeinfo, logger); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at log_generate, stream traceid is %s", pmeinfo->stream_traceid); + KNI_LOG_ERROR(logger, "Failed at log_generate, stream traceid = %s", pmeinfo->stream_traceid); } else{ - KNI_LOG_DEBUG(logger, "Succeed at log_generate, stream traceid is %s", pmeinfo->stream_traceid); + KNI_LOG_DEBUG(logger, "Succeed at log_generate, stream traceid = %s", pmeinfo->stream_traceid); } } //intercept traffic stat @@ -462,13 +461,6 @@ static void stream_destroy(struct pme_info *pmeinfo){ pmeinfo->server_bytes + pmeinfo->client_bytes); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TFE_INTCP_STM], 0, FS_OP_ADD, 1); } - //only intercetp stream need del htable - if(pmeinfo->action == KNI_ACTION_INTERCEPT){ - //del keepalive_replay_htable - if(g_kni_handle->keepalive_replay_switch == 1){ - keepalive_replay_htable_del(pmeinfo); - } - } //free pme pme_info_destroy(pmeinfo); } @@ -490,7 +482,7 @@ static int judge_stream_can_destroy(struct pme_info *pmeinfo, int caller){ pthread_mutex_unlock(&(pmeinfo->lock)); } else{ - KNI_LOG_ERROR(logger, "Failed at judge_stream_can_destroy, pmeinfo is null"); + KNI_LOG_ERROR(logger, "Failed at judge_stream_can_destroy, pmeinfo = null"); } return can_destroy; } @@ -532,7 +524,7 @@ static int wrapped_kni_cmsg_set(struct kni_cmsg *cmsg, uint16_t type, const unsi void *logger = g_kni_handle->local_logger; int ret = kni_cmsg_set(cmsg, type, value, size); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed set cmsg, type is %d, stream traceid is %s", type, stream_traceid); + KNI_LOG_ERROR(logger, "Failed set cmsg, type = %d, stream traceid = %s", type, stream_traceid); } return ret; } @@ -579,10 +571,10 @@ static unsigned char* kni_cmsg_serialize_header_new(struct pme_info *pmeinfo, st ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_SACK_SERVER, (const unsigned char*)&(pmeinfo->server_tcpopt->sack), 1, pmeinfo->stream_traceid); if(ret < 0) goto error_out; //client timestamp - ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT, (const unsigned char*)&(pmeinfo->client_tcpopt->ts), 1, pmeinfo->stream_traceid); + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT, (const unsigned char*)&(pmeinfo->client_tcpopt->ts_set), 1, pmeinfo->stream_traceid); if(ret < 0) goto error_out; //server timestamp - ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER, (const unsigned char*)&(pmeinfo->server_tcpopt->ts), 1, pmeinfo->stream_traceid); + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER, (const unsigned char*)&(pmeinfo->server_tcpopt->ts_set), 1, pmeinfo->stream_traceid); if(ret < 0) goto error_out; //protocol ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (const unsigned char*)&protocol_type, 1, pmeinfo->stream_traceid); @@ -608,7 +600,7 @@ static unsigned char* kni_cmsg_serialize_header_new(struct pme_info *pmeinfo, st serialize_len = 0; ret = kni_cmsg_serialize(cmsg, buff, bufflen, &serialize_len); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at serialize cmsg, ret is %d, stream traceid is %s", + KNI_LOG_ERROR(logger, "Failed at serialize cmsg, ret = %d, stream traceid = %s", ret, pmeinfo->stream_traceid); goto error_out; } @@ -688,7 +680,7 @@ static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_ } } if(index == -1){ - KNI_LOG_ERROR(logger, "tfd %d is disabled"); + KNI_LOG_ERROR(logger, "tfd %d = disabled"); return -1; } struct mr_vdev *dev_eth_handler = handle->tfe_enabled_nodes[index].dev_eth_handler; @@ -699,7 +691,7 @@ static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_ int nr_send = 1; int alloc_ret = marsio_buff_malloc_device(dev_eth_handler, tx_buffs, nr_send, 0, thread_seq); if (alloc_ret < 0){ - KNI_LOG_ERROR(logger, "Failed at alloc marsio buffer, ret is %d, thread_seq is %d", + KNI_LOG_ERROR(logger, "Failed at alloc marsio buffer, ret = %d, thread_seq = %d", alloc_ret, thread_seq); return -1; } @@ -727,10 +719,9 @@ static int wrapped_kni_header_parse(const void *a_packet, struct pme_info *pmein int ret = kni_ipv6_header_parse(a_packet, pktinfo); if(ret < 0){ char *errmsg = kni_ipv6_errmsg_get((enum kni_ipv6hdr_parse_error)ret); - KNI_LOG_ERROR(logger, "Failed at parse ipv6 header, errmsg is %s, stream treaceid is %s", + KNI_LOG_DEBUG(logger, "Stream error: failed at parse ipv6 header, errmsg = %s, stream treaceid = %s", errmsg, pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_IPV6HDR_PARSE_FAIL; return -1; } } @@ -738,151 +729,314 @@ static int wrapped_kni_header_parse(const void *a_packet, struct pme_info *pmein int ret = kni_ipv4_header_parse(a_packet, pktinfo); if(ret < 0){ char *errmsg = kni_ipv4_errmsg_get((enum kni_ipv4hdr_parse_error)ret); - KNI_LOG_ERROR(logger, "Failed at parse ipv4 header, errmsg is %s, stream treaceid is %s", + KNI_LOG_ERROR(logger, "Stream error: failed at parse ipv4 header, errmsg = %s, stream treaceid = %s", errmsg, pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV4HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_IPV4HDR_PARSE_FAIL; return -1; } } return 0; } -static char pending_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet){ - //void *logger = g_kni_handle->local_logger; +static int tuple2stream_htable_key_get_v4_by_packet(struct pkt_info *pktinfo, struct stream_tuple4_v4 *key, int *reversed){ + if(pktinfo->iphdr.v4->saddr < pktinfo->iphdr.v4->daddr){ + key->saddr = pktinfo->iphdr.v4->saddr; + key->daddr = pktinfo->iphdr.v4->daddr; + key->source = pktinfo->tcphdr->source; + key->dest = pktinfo->tcphdr->dest; + *reversed = 0; + } + else{ + key->saddr = pktinfo->iphdr.v4->daddr; + key->daddr = pktinfo->iphdr.v4->saddr; + key->source = pktinfo->tcphdr->dest; + key->dest = pktinfo->tcphdr->source; + *reversed = 1; + } + return 0; +} + +static int tuple2stream_htable_key_get_v6_by_packet(struct pkt_info *pktinfo, struct stream_tuple4_v6 *key, int *reversed){ + if(memcmp((void*)&(pktinfo->iphdr.v6->ip6_src), (void*)&(pktinfo->iphdr.v6->ip6_dst), sizeof(key->saddr)) < 0){ + memcpy(key->saddr, &(pktinfo->iphdr.v6->ip6_src), sizeof(key->saddr)); + memcpy(key->daddr, &(pktinfo->iphdr.v6->ip6_dst), sizeof(key->daddr)); + key->source = pktinfo->tcphdr->source; + key->dest = pktinfo->tcphdr->dest; + *reversed = 0; + } + else{ + memcpy(key->saddr, &(pktinfo->iphdr.v6->ip6_dst), sizeof(key->saddr)); + memcpy(key->daddr, &(pktinfo->iphdr.v6->ip6_src), sizeof(key->daddr)); + key->source = pktinfo->tcphdr->dest; + key->dest = pktinfo->tcphdr->source; + *reversed = 1; + } + return 0; +} + +static int tuple2stream_htable_key_get_v4_by_stream(const struct streaminfo *stream, struct stream_tuple4_v4 *key, int *reversed){ + if(stream->addr.tuple4_v4->saddr < stream->addr.tuple4_v4->daddr){ + key->saddr = stream->addr.tuple4_v4->saddr; + key->daddr = stream->addr.tuple4_v4->daddr; + key->source = stream->addr.tuple4_v4->source; + key->dest = stream->addr.tuple4_v4->dest; + *reversed = 0; + } + else{ + key->saddr = stream->addr.tuple4_v4->daddr; + key->daddr = stream->addr.tuple4_v4->saddr; + key->source = stream->addr.tuple4_v4->dest; + key->dest = stream->addr.tuple4_v4->source; + *reversed = 1; + } + return 0; +} + +static int tuple2stream_htable_key_get_v6_by_stream(const struct streaminfo *stream, struct stream_tuple4_v6 *key, int *reversed){ + if(memcmp(stream->addr.tuple4_v6->saddr, stream->addr.tuple4_v6->daddr, sizeof(key->saddr)) < 0){ + memcpy(key->saddr, stream->addr.tuple4_v6->saddr, sizeof(key->saddr)); + memcpy(key->daddr, stream->addr.tuple4_v6->daddr, sizeof(key->daddr)); + key->source = stream->addr.tuple4_v6->source; + key->dest = stream->addr.tuple4_v6->dest; + *reversed = 0; + } + else{ + memcpy(key->saddr, stream->addr.tuple4_v6->daddr, sizeof(key->saddr)); + memcpy(key->daddr, stream->addr.tuple4_v6->saddr, sizeof(key->daddr)); + key->source = stream->addr.tuple4_v6->dest; + key->dest = stream->addr.tuple4_v6->source; + *reversed = 1; + } + return 0; +} + + +static int tuple2stream_htable_add(MESA_htable_handle tuple2stream_htable, addr_type_t addr_type, struct pkt_info *pktinfo, + struct streaminfo *stream, struct pme_info *pmeinfo){ + void *logger = g_kni_handle->local_logger; + int ret; + struct tuple2stream_htable_value *value = ALLOC(struct tuple2stream_htable_value, 1); + value->stream = stream; + value->pmeinfo = pmeinfo; + value->route_dir = stream->routedir; + //ipv6 + if(addr_type == ADDR_TYPE_IPV6){ + struct stream_tuple4_v6 key; + tuple2stream_htable_key_get_v6_by_packet(pktinfo, &key, &(value->reversed)); + ret = MESA_htable_add(tuple2stream_htable, (const unsigned char *)&key, sizeof(key), (const void*)value); + if(ret < 0){ + char key_str[KNI_ADDR_MAX]; + kni_addr_trans_v6(&key, key_str, sizeof(key_str)); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1); + KNI_LOG_ERROR(logger, "MESA_htable: Failed at add, table = tuple2stream_htable, key = %s, key_size = %d, ret = %d", + key_str, sizeof(key), ret); + } + else{ + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_SUCC], 0, FS_OP_ADD, 1); + } + } + //ipv4 + else{ + struct stream_tuple4_v4 key; + tuple2stream_htable_key_get_v4_by_packet(pktinfo, &key, &(value->reversed)); + ret = MESA_htable_add(tuple2stream_htable, (const unsigned char *)&key, sizeof(key), (const void*)value); + if(ret < 0){ + char key_str[KNI_ADDR_MAX]; + kni_addr_trans_v4(&key, key_str, sizeof(key_str)); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1); + KNI_LOG_ERROR(logger, "MESA_htable: Failed at add, table = tuple2stream_htable, key = %s, key_size = %d, ret = %d", + key_str, sizeof(key), ret); + } + else{ + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_SUCC], 0, FS_OP_ADD, 1); + } + } + return ret; +} + + +static char pending_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){ + void *logger = g_kni_handle->local_logger; struct pkt_info pktinfo; int ret = wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo); if(ret < 0){ + pmeinfo->error = STREAM_ERROR_IPHDR_PARSE_FAIL; return APP_STATE_FAWPKT | APP_STATE_DROPME; } if(!pktinfo.tcphdr->syn){ //pending_opstate not syn, bypass and dropme - //KNI_LOG_DEBUG(logger, "pending opstate: not syn, stream traceid is %s", pmeinfo->stream_traceid); + KNI_LOG_DEBUG(logger, "Stream error: pending opstate, not syn, stream traceid = %s", pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SYN], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_PENDING_NO_SYN; return APP_STATE_FAWPKT | APP_STATE_DROPME; } + + //dup traffic detect + if(g_kni_handle->dup_traffic_switch == 1){ + if(pmeinfo->syn_packet == NULL){ + struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1); + dup_traffic_dabloom_key_get(&pktinfo, syn_packet); + pmeinfo->syn_packet = syn_packet; + } + else{ + struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1); + dup_traffic_dabloom_key_get(&pktinfo, syn_packet); + if(memcmp(pmeinfo->syn_packet, syn_packet, sizeof(*syn_packet)) == 0){ + pmeinfo->has_dup_syn = 1; + } + FREE(&(pmeinfo->syn_packet)); + pmeinfo->syn_packet = syn_packet; + } + } pmeinfo->client_window = ntohs(pktinfo.tcphdr->window); pmeinfo->client_tcpopt = kni_get_tcpopt(pktinfo.tcphdr, pktinfo.tcphdr_len); return APP_STATE_FAWPKT | APP_STATE_GIVEME; } -int keepalive_replay_htable_add(const struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, char *stream_addr, int *sapp_ret){ +static int traceid2pme_htable_add(struct pme_info *pmeinfo){ void *logger = g_kni_handle->local_logger; int key_size =0, ret; - struct keepalive_replay_htable_value *c2s_value = ALLOC(struct keepalive_replay_htable_value, 1); - //c2s_value->first_data_len = pktinfo->data_len; - c2s_value->window = pmeinfo->server_window; - struct stream_tuple4_v4 *c2s_key_v4 = NULL; - struct stream_tuple4_v6 *c2s_key_v6 = NULL; - if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ - c2s_key_v6 = stream->addr.tuple4_v6; - key_size = sizeof(*c2s_key_v6); - ret = MESA_htable_add(g_kni_handle->keepalive_replay_htable, (const unsigned char *)c2s_key_v6, key_size, (const void*)c2s_value); - } - else{ - c2s_key_v4 = stream->addr.tuple4_v4; - key_size = sizeof(*c2s_key_v4); - ret = MESA_htable_add(g_kni_handle->keepalive_replay_htable, (const unsigned char *)c2s_key_v4, key_size, (const void*)c2s_value); - } - if(ret < 0){ - //tfe not release, sapp release but not expire, so the same stream can not add, bypass and dropme - if(ret != MESA_HTABLE_RET_DUP_ITEM){ - KNI_LOG_ERROR(logger, "MESA_htable: Failed at add, table is keepalive_replay_htable, " - "dir is c2s, key is %s, key_size is %d, ret is %d", stream_addr, key_size, ret); - } - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KA_ADD_FAIL], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_KA_REPLAY_ADD_FAIL; - *sapp_ret = APP_STATE_FAWPKT | APP_STATE_DROPME; - return -1; - } - else{ - //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at add, table is keepalive_replay_htable, " - // "dir is c2s, key is %s, key_size is %d", stream_addr, key_size); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC], 0, FS_OP_ADD, 1); - } - //s2c - struct keepalive_replay_htable_value *s2c_value = ALLOC(struct keepalive_replay_htable_value, 1); - s2c_value->first_data_len = pktinfo->data_len; - s2c_value->window = pmeinfo->client_window; - if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ - struct stream_tuple4_v6 s2c_key_v6; - key_size = sizeof(s2c_key_v6); - memcpy(s2c_key_v6.saddr, c2s_key_v6->daddr, sizeof(s2c_key_v6.saddr)); - memcpy(s2c_key_v6.daddr, c2s_key_v6->saddr, sizeof(s2c_key_v6.daddr)); - s2c_key_v6.source = c2s_key_v6->dest; - s2c_key_v6.dest = c2s_key_v6->source; - ret = MESA_htable_add(g_kni_handle->keepalive_replay_htable, (const unsigned char *)(&s2c_key_v6), - key_size, (const void*)s2c_value); - } - else{ - struct stream_tuple4_v4 s2c_key_v4; - key_size = sizeof(s2c_key_v4); - s2c_key_v4.saddr = c2s_key_v4->daddr; - s2c_key_v4.daddr = c2s_key_v4->saddr; - s2c_key_v4.source = c2s_key_v4->dest; - s2c_key_v4.dest = c2s_key_v4->source; - ret = MESA_htable_add(g_kni_handle->keepalive_replay_htable, (const unsigned char *)(&s2c_key_v4), - key_size, (const void*)s2c_value); - } - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_htable: Failed at add, table is keepalive_replay_htable, " - "dir is s2c, key is %s, key_size is %d, ret is %d", stream_addr, key_size, ret); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KA_ADD_FAIL], 0, FS_OP_ADD, 1); - } - else{ - //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at add, table is keepalive_replay_htable, " - // "dir is s2c, key is %s, key_size is %d", stream_addr, key_size); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC], 0, FS_OP_ADD, 1); - } - return 0; -} -static int first_data_intercept(const struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, char *stream_addr, int thread_seq){ - void *logger = g_kni_handle->local_logger; - int key_size =0, ret; - if(g_kni_handle->keepalive_replay_switch == 1){ - int sapp_ret; - ret = keepalive_replay_htable_add(stream, pmeinfo, pktinfo, stream_addr, &sapp_ret); - if(ret < 0){ - return sapp_ret; - } - } - //only intercept: add to traceid2pme htable key_size = strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid)); ret = MESA_htable_add(g_kni_handle->traceid2pme_htable, (const unsigned char *)(pmeinfo->stream_traceid), key_size, (const void*)pmeinfo); if(ret < 0){ KNI_LOG_ERROR(logger, "MESA_htable: Failed at add," - "table is traceid2pme_htable, key is %s, ret is %d", pmeinfo->stream_traceid, ret); + "table = traceid2pme_htable, key = %s, ret = %d", pmeinfo->stream_traceid, ret); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_ADD_FAIL], 0, FS_OP_ADD, 1); } else{ - //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at add," - // "table is traceid2pme_htable, key is %s", pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_ADD_SUCC], 0, FS_OP_ADD, 1); } + return ret; +} +int tuple2stream_htable_del(MESA_htable_handle handle, const struct streaminfo *stream){ + void *logger = g_kni_handle->local_logger; + int reversed = 0, ret; + //ipv6 + if(stream->addr.addrtype == ADDR_TYPE_IPV6){ + struct stream_tuple4_v6 key; + tuple2stream_htable_key_get_v6_by_stream(stream, &key, &reversed); + ret = MESA_htable_del(handle, (const unsigned char *)(&key), + sizeof(key), NULL); + if(ret < 0){ + char key_str[KNI_ADDR_MAX]; + kni_addr_trans_v6(&key, key_str, sizeof(key_str)); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_FAIL], 0, FS_OP_ADD, 1); + KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table = %s, key = %s, key_size = %d, ret = %d", + "tuple2stream_htable", key_str, sizeof(key), ret); + } + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_SUCC], 0, FS_OP_ADD, 1); + } + //ipv4 + else{ + struct stream_tuple4_v4 key; + tuple2stream_htable_key_get_v4_by_stream(stream, &key, &reversed); + ret = MESA_htable_del(handle, (const unsigned char *)(&key), sizeof(key), NULL); + if(ret < 0){ + char key_str[KNI_ADDR_MAX]; + kni_addr_trans_v4(&key, key_str, sizeof(key_str)); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_FAIL], 0, FS_OP_ADD, 1); + KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table = %s, key = %s, key_size = %d, ret = %d", + "tuple2stream_htable", key_str, sizeof(key), ret); + } + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_SUCC], 0, FS_OP_ADD, 1); + } + return ret; +} + +static void traceid2pme_htable_del(struct pme_info *pmeinfo){ + //del traceid2pme htable + if(pmeinfo->action == KNI_ACTION_INTERCEPT){ + void *logger = g_kni_handle->local_logger; + int key_size = strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid)); + int ret; + ret = MESA_htable_del(g_kni_handle->traceid2pme_htable, (const unsigned char *)pmeinfo->stream_traceid, + key_size, NULL); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table = %s, key = %s, key_size = %d, ret = %d", + "traceid2pme_htable", pmeinfo->stream_traceid, key_size, ret); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_FAIL], 0, FS_OP_ADD, 1); + } + else{ + //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at del, table = %s, key = %s, key_size = %d", + // "traceid2pme_htable", pmeinfo->stream_traceid, key_size); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC], 0, FS_OP_ADD, 1); + } + } +} + +static int first_data_intercept(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, char *stream_addr, int thread_seq){ + void *logger = g_kni_handle->local_logger; + int ret; + //only intercept: add to tuple2stream_htable + ret = tuple2stream_htable_add(g_kni_handle->threads_handle[thread_seq].tuple2stream_htable, pmeinfo->addr_type, pktinfo, stream, pmeinfo); + if(ret < 0){ + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1); + KNI_LOG_DEBUG(logger, "Stream error: tuple2stm add fail, stream traceid = %s", pmeinfo->stream_traceid); + pmeinfo->error = STREAM_ERROR_TUPLE2STM_ADD_FAIL; + return APP_STATE_FAWPKT | APP_STATE_DROPME; + } + //only intercept: add to traceid2pme htable + traceid2pme_htable_add(pmeinfo); //action = KNI_ACTION_INTERCEPT, sendto tfe int len = 0; char *buff = add_cmsg_to_packet(pmeinfo, pktinfo, &len); ret = send_to_tfe(g_kni_handle->marsio_handle, buff, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); + KNI_LOG_DEBUG(logger, "Stream error: failed at send first packet to tfe%d, stream traceid = %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_SENDTO_TFE_FAIL; FREE(&buff); + tuple2stream_htable_del(g_kni_handle->threads_handle[thread_seq].tuple2stream_htable, stream); + traceid2pme_htable_del(pmeinfo); return APP_STATE_FAWPKT | APP_STATE_DROPME; } else{ - KNI_LOG_DEBUG(logger, "Succeed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); + KNI_LOG_DEBUG(logger, "Succeed at send first packet to tfe%d, stream traceid = %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); } FREE(&buff); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_STM], 0, FS_OP_ADD, 1); return APP_STATE_DROPPKT | APP_STATE_GIVEME; } -static char data_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){ - //pmeinfo->tfe_release = 1: intercept, tfe end first. so droppkt and dropme +static int dabloom_search(struct pkt_info *pktinfo, int thread_seq){ + void *logger = g_kni_handle->local_logger; + struct dup_traffic_dabloom_key bloom_key; + memset(&bloom_key, 0, sizeof(bloom_key)); + dup_traffic_dabloom_key_get(pktinfo, &bloom_key); + int ret = expiry_dablooms_search(g_kni_handle->threads_handle[thread_seq].dabloom_handle, (const char*)&bloom_key, sizeof(bloom_key)); + //ret = 1, = dup packet, bypass the packet + if(ret < 0){ + KNI_LOG_ERROR(logger, "Failed at expiry_dablooms_search, errmsg = %s", expiry_dablooms_errno_trans((enum expiry_dablooms_errno)ret)); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_FAIL], 0, FS_OP_ADD, 1); + } + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_SUCC], 0, FS_OP_ADD, 1); + uint64_t count = 0; + expiry_dablooms_element_count_get(g_kni_handle->threads_handle[thread_seq].dabloom_handle, &count); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[0], g_kni_fs_handle->column_ids[thread_seq], FS_OP_SET, count); + return ret; +} + +static int dabloom_add(struct pkt_info *pktinfo, int thread_seq){ + void *logger = g_kni_handle->local_logger; + struct dup_traffic_dabloom_key bloom_key; + memset(&bloom_key, 0, sizeof(bloom_key)); + dup_traffic_dabloom_key_get(pktinfo, &bloom_key); + int ret = expiry_dablooms_add(g_kni_handle->threads_handle[thread_seq].dabloom_handle, (const char*)&bloom_key, sizeof(bloom_key)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "Failed at expiry_dablooms_add, errmsg = %s", expiry_dablooms_errno_trans((enum expiry_dablooms_errno)ret)); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_ADD_FAIL], 0, FS_OP_ADD, 1); + } + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_ADD_SUCC], 0, FS_OP_ADD, 1); + uint64_t count = 0; + expiry_dablooms_element_count_get(g_kni_handle->threads_handle[thread_seq].dabloom_handle, &count); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[0], g_kni_fs_handle->column_ids[thread_seq], FS_OP_SET, count); + return ret; +} + +static char data_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){ + //pmeinfo->tfe_release = 1: intercept, tfe end first. DO NOT droppkt and dropme if(pmeinfo->tfe_release == 1){ pmeinfo->server_bytes=stream->ptcpdetail->serverbytes; pmeinfo->client_bytes=stream->ptcpdetail->clientbytes; @@ -898,12 +1052,34 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein struct ip6_hdr *ipv6_hdr = NULL; uint16_t len = 0, ret; char stream_addr[KNI_SYMBOL_MAX] = ""; - kni_stream_addr_trans(&(stream->addr), pmeinfo->addr_type, stream_addr, sizeof(stream_addr)); + if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ + kni_addr_trans_v6(stream->addr.tuple4_v6, stream_addr, sizeof(stream_addr)); + } + else{ + kni_addr_trans_v4(stream->addr.tuple4_v4, stream_addr, sizeof(stream_addr)); + } + //parse ipv4/6 header + struct pkt_info pktinfo; + ret = wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo); + if(ret < 0){ + pmeinfo->error = STREAM_ERROR_IPHDR_PARSE_FAIL; + return APP_STATE_FAWPKT | APP_STATE_DROPME; + } //pmeinfo->action has only 3 value: KNI_ACTION_NONE, KNI_ACTION_INTERCEPT, KNI_ACTION_BYPASS switch (pmeinfo->action){ case KNI_ACTION_NONE: break; case KNI_ACTION_INTERCEPT: + //search dabloom + if(g_kni_handle->dup_traffic_switch == 1){ + if(pmeinfo->has_dup_traffic == 1){ + //ret = 1, = dup packet, bypass the packet + ret = dabloom_search(&pktinfo, thread_seq); + if(ret == 1){ + return APP_STATE_FAWPKT | APP_STATE_GIVEME; + } + } + } if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ ipv6_hdr = (struct ip6_hdr*)a_packet; len = ntohs(ipv6_hdr->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr); @@ -914,7 +1090,7 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein } ret = send_to_tfe(g_kni_handle->marsio_handle, (char*)a_packet, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at send continue packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); + KNI_LOG_ERROR(logger, "Failed at send continue packet to tfe%d, stream traceid = %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1); } return APP_STATE_DROPPKT | APP_STATE_GIVEME; @@ -924,16 +1100,10 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein assert(0); break; } - //parse ipv4/6 header - struct pkt_info pktinfo; - ret = wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo); - if(ret < 0){ - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } //first data > 1500, bypass and dropme if(pktinfo.ip_totlen > KNI_DEFAULT_MTU){ pmeinfo->error = STREAM_ERROR_EXCEED_MTU; - KNI_LOG_ERROR(logger, "first data packet exceed MTU(1500), bypass and dropme"); + KNI_LOG_DEBUG(logger, "Stream error: first data packet exceed MTU(1500), stream traceid = %s", pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_EXCEED_MTU], 0, FS_OP_ADD, 1); return APP_STATE_FAWPKT | APP_STATE_DROPME; } @@ -941,6 +1111,23 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein if(pktinfo.tcphdr->syn && pktinfo.tcphdr->ack){ pmeinfo->server_window = ntohs(pktinfo.tcphdr->window); pmeinfo->server_tcpopt = kni_get_tcpopt(pktinfo.tcphdr, pktinfo.tcphdr_len); + //dup traffic detect + if(g_kni_handle->dup_traffic_switch == 1){ + if(pmeinfo->syn_ack_packet == NULL){ + struct dup_traffic_dabloom_key *syn_ack_packet = ALLOC(struct dup_traffic_dabloom_key, 1); + dup_traffic_dabloom_key_get(&pktinfo, syn_ack_packet); + pmeinfo->syn_ack_packet = syn_ack_packet; + } + else{ + struct dup_traffic_dabloom_key *syn_ack_packet = ALLOC(struct dup_traffic_dabloom_key, 1); + dup_traffic_dabloom_key_get(&pktinfo, syn_ack_packet); + if(memcmp(pmeinfo->syn_ack_packet, syn_ack_packet, sizeof(*syn_ack_packet)) == 0){ + pmeinfo->has_dup_syn_ack = 1; + } + FREE(&(pmeinfo->syn_ack_packet)); + pmeinfo->syn_ack_packet = syn_ack_packet; + } + } return APP_STATE_FAWPKT | APP_STATE_GIVEME; } //no data, maybe ack @@ -949,7 +1136,7 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein } //not double dir, bypass and dropme if(stream->dir != DIR_DOUBLE){ - //KNI_LOG_DEBUG(logger, "dir is %d, bypass, stream addr is %s", stream->dir, stream_addr); + KNI_LOG_DEBUG(logger, "Stream error: single dir = %d, stream traceid = %s", stream->dir, pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SINGLE_DIR], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_SINGLE_DIR; return APP_STATE_FAWPKT | APP_STATE_DROPME; @@ -961,8 +1148,7 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein switch(pmeinfo->protocol){ //can not identify protocol from first data packet, bypass and dropme case KNI_PROTOCOL_UNKNOWN: - KNI_LOG_DEBUG(logger, "Failed at protocol_identify, bypass and dropme, stream addr is %s\n", - pmeinfo->protocol, stream_addr); + KNI_LOG_DEBUG(logger, "Stream error: failed at protocol_identify, stream traceid = %s", pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PROTO_UNKNOWN], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_PROTOCOL_UNKNOWN; return APP_STATE_FAWPKT | APP_STATE_DROPME; @@ -977,40 +1163,58 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein default: break; } - pmeinfo->action = intercept_policy_scan(g_kni_handle->maat_handle, (struct ipaddr*)(&stream->addr), - protocol_identify_res.domain, protocol_identify_res.domain_len, - thread_seq, &(pmeinfo->policy_id), &(pmeinfo->do_log), &(pmeinfo->maat_hit)); - //policy scan log - char *action_str = kni_maat_action_trans(pmeinfo->action); - KNI_LOG_INFO(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d, stream traceid is %s", - stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit, pmeinfo->stream_traceid); //receive client hello, but no syn/ack, bypass and dropme if(pmeinfo->client_tcpopt == NULL || pmeinfo->server_tcpopt == NULL){ - KNI_LOG_ERROR(logger, "Failed at intercept, %s, %s, stream traceid is %s", pmeinfo->client_tcpopt == NULL ? "no syn" : "have syn", + KNI_LOG_DEBUG(logger, "Stream error: %s, %s, stream traceid = %s", pmeinfo->client_tcpopt == NULL ? "no syn" : "have syn", pmeinfo->server_tcpopt == NULL ? "no syn/ack" : "have syn/ack", pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SA], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_NO_SYN_ACK; return APP_STATE_FAWPKT | APP_STATE_DROPME; } + //dup_traffic_check + if(g_kni_handle->dup_traffic_switch == 1){ + //has dup traffic + if(pmeinfo->has_dup_syn == 1 || pmeinfo->has_dup_syn_ack == 1){ + pmeinfo->has_dup_traffic = 1; + } + if(pmeinfo->has_dup_traffic == 1){ + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DUP_TFC_STM], 0, FS_OP_ADD, 1); + if(g_kni_handle->dup_traffic_action == KNI_ACTION_BYPASS){ + pmeinfo->action = KNI_ACTION_BYPASS; + pmeinfo->intercept_state=0; + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_DUP_TFC], 0, FS_OP_ADD, 1); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); + return APP_STATE_FAWPKT | APP_STATE_GIVEME; //GIVEME: for session record + } + } + } + pmeinfo->action = intercept_policy_scan(g_kni_handle->maat_handle, (struct ipaddr*)(&stream->addr), + protocol_identify_res.domain, protocol_identify_res.domain_len, + thread_seq, &(pmeinfo->policy_id), &(pmeinfo->do_log), &(pmeinfo->maat_hit)); + //policy scan log + char *action_str = kni_maat_action_trans(pmeinfo->action); + KNI_LOG_INFO(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d, stream traceid = %s", + stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit, pmeinfo->stream_traceid); switch(pmeinfo->action){ case KNI_ACTION_BYPASS: - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_POLICY_BYP], 0, FS_OP_ADD, 1); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_POLICY], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); pmeinfo->intercept_state=0; - return APP_STATE_FAWPKT | APP_STATE_GIVEME; + return APP_STATE_FAWPKT | APP_STATE_GIVEME; //GIVEME: for session record case KNI_ACTION_INTERCEPT: pmeinfo->intercept_state=1; return first_data_intercept(stream, pmeinfo, &pktinfo, stream_addr, thread_seq); default: //action != intercept && action != bypass,bypass and dropme - KNI_LOG_ERROR(logger, "Action %d(%s) is invalid, bypass(dropme): policy_id is %d, stream addr is %s, domain is ", - pmeinfo->action, action_str, pmeinfo->policy_id, stream_addr, protocol_identify_res.domain); + KNI_LOG_DEBUG(logger, "Stream error: action %d(%s) = invalid: policy_id = %d, stream traceid = %s, domain = ", + pmeinfo->action, action_str, pmeinfo->policy_id, pmeinfo->stream_traceid, protocol_identify_res.domain); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ACTION_INVALID], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_INVALID_ACTION; return APP_STATE_FAWPKT | APP_STATE_DROPME; } } + static char close_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, int thread_seq){ //close: a_packet = null, do not sendto tfe clock_gettime(CLOCK_REALTIME, &(pmeinfo->end_time)); @@ -1025,9 +1229,10 @@ static char close_opstate(const struct streaminfo *stream, struct pme_info *pmei //reset clock: when sapp end, start clock MESA_htable_search(g_kni_handle->traceid2pme_htable, (const unsigned char*)pmeinfo->stream_traceid, strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid))); + tuple2stream_htable_del(g_kni_handle->threads_handle[thread_seq].tuple2stream_htable, stream); return APP_STATE_DROPPKT | APP_STATE_DROPME; case KNI_ACTION_BYPASS: - //KNI_LOG_DEBUG(logger, "action is bypass, set tfe_release = 1, stream_trace_id is %s", pmeinfo->stream_traceid); + //KNI_LOG_DEBUG(logger, "action = bypass, set tfe_release = 1, stream_trace_id = %s", pmeinfo->stream_traceid); pmeinfo->tfe_release = 1; return APP_STATE_FAWPKT | APP_STATE_DROPME; //stream has only syn, ack. no data. @@ -1035,35 +1240,14 @@ static char close_opstate(const struct streaminfo *stream, struct pme_info *pmei char *action_str = kni_maat_action_trans(pmeinfo->action); pmeinfo->error = STREAM_ERROR_NO_DATA; FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_DATA], 0, FS_OP_ADD, 1); - KNI_LOG_DEBUG(logger, "close_opstate: action %d(%s) is abnormal, stream_traceid is %s", + KNI_LOG_DEBUG(logger, "Stream error: close_opstate, action %d(%s) = abnormal, stream_traceid = %s", pmeinfo->action, action_str, pmeinfo->stream_traceid); return APP_STATE_FAWPKT | APP_STATE_DROPME; } } -static void traceid2pme_htable_del(struct pme_info *pmeinfo){ - //del traceid2pme htable - if(pmeinfo->action == KNI_ACTION_INTERCEPT){ - void *logger = g_kni_handle->local_logger; - int key_size = strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid)); - int ret; - ret = MESA_htable_del(g_kni_handle->traceid2pme_htable, (const unsigned char *)pmeinfo->stream_traceid, - key_size, NULL); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table is %s, key is %s, key_size is %d, ret is %d", - "traceid2pme_htable", pmeinfo->stream_traceid, key_size, ret); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_FAIL], 0, FS_OP_ADD, 1); - } - else{ - //KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at del, table is %s, key is %s, key_size is %d", - // "traceid2pme_htable", pmeinfo->stream_traceid, key_size); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC], 0, FS_OP_ADD, 1); - } - } -} - //from syn -extern "C" char kni_tcpall_entry(const struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){ +extern "C" char kni_tcpall_entry(struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){ void *logger = g_kni_handle->local_logger; int ret; @@ -1090,20 +1274,20 @@ extern "C" char kni_tcpall_entry(const struct streaminfo *stream, void** pme, in if(pmeinfo == NULL){ KNI_LOG_ERROR(logger, "Failed at new pmeinfo, bypass and dropme"); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_NEW_FAIL], 0, FS_OP_ADD, 1); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_PME_NEW_FAIL], 0, FS_OP_ADD, 1); return APP_STATE_FAWPKT | APP_STATE_DROPME; } FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_NEW_SUCC], 0, FS_OP_ADD, 1); pmeinfo->tfe_id = tfe_mgr_alive_node_get(g_kni_handle->_tfe_mgr, thread_seq); - //printf("tfe_id is %d\n", pmeinfo->tfe_id); + //printf("tfe_id = %d\n", pmeinfo->tfe_id); if(pmeinfo->tfe_id < 0){ KNI_LOG_ERROR(logger, "No alive tfe available, bypass and dropme"); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_TFE], 0, FS_OP_ADD, 1); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_NO_TFE], 0, FS_OP_ADD, 1); pme_info_destroy(pmeinfo); return APP_STATE_FAWPKT | APP_STATE_DROPME; } - ret = pending_opstate(stream, pmeinfo, a_packet); + ret = pending_opstate(stream, pmeinfo, a_packet, thread_seq); if(pmeinfo->error < 0){ goto error_out; } @@ -1125,27 +1309,27 @@ extern "C" char kni_tcpall_entry(const struct streaminfo *stream, void** pme, in default: ret = APP_STATE_FAWPKT | APP_STATE_GIVEME; FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STATE_UNKNOWN], 0, FS_OP_ADD, 1); - KNI_LOG_ERROR(logger, "Unknown stream opstate %d, stream traceid is %s", stream->pktstate, pmeinfo->stream_traceid); + KNI_LOG_ERROR(logger, "Unknown stream opstate %d, stream traceid = %s", stream->pktstate, pmeinfo->stream_traceid); break; } //sapp release: bypass or intercept if((ret & APP_STATE_DROPME)){ can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_SAPP); if(can_destroy == 1){ - traceid2pme_htable_del(pmeinfo); - stream_destroy(pmeinfo); + if(pmeinfo->action == KNI_ACTION_INTERCEPT){ + traceid2pme_htable_del(pmeinfo); + } + stream_destroy(pmeinfo, pmeinfo->do_log); } } return ret; -//error out: no hash, no sendlog, just destroy_pme +//error out: stream error, send log and destroy_pme, do not need to del htable error_out: - char *stream_errmsg = stream_errmsg_get(pmeinfo->error); - KNI_LOG_DEBUG(logger, "stream error is %s, bypass and dropme, stream traceid is %s", stream_errmsg, pmeinfo->stream_traceid); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STM_ERR], 0, FS_OP_ADD, 1); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_ERR], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); if(pmeinfo != NULL){ - pme_info_destroy(pmeinfo); + stream_destroy(pmeinfo, 1); } return ret; } @@ -1158,12 +1342,12 @@ static int http_project_init(){ void *logger = g_kni_handle->local_logger; int id = project_producer_register(HTTP_PROJECT_NAME, PROJECT_VAL_TYPE_STRUCT, http_project_free); if(id < 0){ - KNI_LOG_ERROR(logger, "Failed at project_producer_register, project name is %s, ret is %d", HTTP_PROJECT_NAME, id); + KNI_LOG_ERROR(logger, "Failed at project_producer_register, project name = %s, ret = %d", HTTP_PROJECT_NAME, id); return -1; } id = project_customer_register(HTTP_PROJECT_NAME, PROJECT_VAL_TYPE_STRUCT); if(id < 0){ - KNI_LOG_ERROR(logger, "Failed at project_customer_register, project name is %s, ret is %d", HTTP_PROJECT_NAME, id); + KNI_LOG_ERROR(logger, "Failed at project_customer_register, project name = %s, ret = %d", HTTP_PROJECT_NAME, id); return -1; } return id; @@ -1199,188 +1383,92 @@ static void kni_marsio_destroy(struct kni_marsio_handle *handle){ handle = NULL; } -static void sendto_vxlan(marsio_buff_t *rx_buff, struct mr_sendpath *dev_vxlan_sendpath, int thread_seq){ - //tag - struct mr_tunnat_ctrlzone mr_ctrlzone; - memset(&mr_ctrlzone, 0, sizeof(mr_ctrlzone)); - mr_ctrlzone.action |= (TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER); - marsio_buff_ctrlzone_set(rx_buff, 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); - //send to vxlan, vxlan handler: recv: 0, send: 1, nr_burst must be 1 - int nr_burst = 1; - marsio_send_burst_with_options(dev_vxlan_sendpath, thread_seq, &rx_buff, nr_burst, MARSIO_SEND_OPT_FAST); -} - -static long keepalive_replay_search_cb(void *data, const uchar *key, uint size, void *user_args){ +int tuple2stream_htable_search(MESA_htable_handle handle, struct ethhdr *ether_hdr, int thread_seq){ void *logger = g_kni_handle->local_logger; - struct keepalive_replay_search_cb_args *args = (struct keepalive_replay_search_cb_args*)user_args; - struct kni_marsio_handle *marsio_handle = args->marsio_handle; - marsio_buff_t *rx_buff = args->rx_buff; - int tfe_id = args->tfe_id; - int thread_seq = args->thread_seq; - if(data == NULL){ - sendto_vxlan(rx_buff, marsio_handle->dev_vxlan_sendpath, thread_seq); - return 0; + if(ether_hdr->h_proto != htons(ETH_P_IP) && ether_hdr->h_proto != htons(ETH_P_IPV6)){ + return -1; } - struct keepalive_replay_htable_value *value = (struct keepalive_replay_htable_value*)data; - if(value->has_replayed == 1){ - sendto_vxlan(rx_buff, marsio_handle->dev_vxlan_sendpath, thread_seq); - return 0; - } - //a_packet: window update - void *raw_packet = args->raw_packet; - char *replay_packet = NULL; - uint16_t tot_len = 0; + void *raw_packet = (char*)ether_hdr + sizeof(*ether_hdr); + tuple2stream_htable_value *value = NULL; + struct pkt_info pktinfo; + int reversed = 0, ret; + char key_str[KNI_ADDR_MAX]; //ipv6 - if(args->addr_type == ADDR_TYPE_IPV6){ - - struct pkt_info raw_pktinfo; - int ret = kni_ipv6_header_parse(raw_packet, &raw_pktinfo); + if(ether_hdr->h_proto == htons(ETH_P_IPV6)){ + ret = kni_ipv6_header_parse(raw_packet, &pktinfo); if(ret < 0){ char *errmsg = kni_ipv6_errmsg_get((enum kni_ipv6hdr_parse_error)ret); - KNI_LOG_ERROR(logger, "Failed at parse ipv6 header, send to vxlan, errmsg is %s", errmsg); + KNI_LOG_ERROR(logger, "failed at parse ipv6 header, errmsg = %s", errmsg); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); - sendto_vxlan(rx_buff, marsio_handle->dev_vxlan_sendpath, thread_seq); - return 0; + return -1; } - tot_len = raw_pktinfo.ip_totlen; - replay_packet = ALLOC(char, tot_len); - memcpy(replay_packet, raw_packet, tot_len); - struct pkt_info replay_pktinfo; - kni_ipv6_header_parse(replay_packet, &replay_pktinfo); - replay_pktinfo.iphdr.v6->ip6_src = raw_pktinfo.iphdr.v6->ip6_dst; - replay_pktinfo.iphdr.v6->ip6_dst = raw_pktinfo.iphdr.v6->ip6_src; - replay_pktinfo.tcphdr->source = raw_pktinfo.tcphdr->dest; - replay_pktinfo.tcphdr->dest = raw_pktinfo.tcphdr->source; - replay_pktinfo.tcphdr->seq = htonl(ntohl(raw_pktinfo.tcphdr->ack_seq) + value->first_data_len); - replay_pktinfo.tcphdr->ack_seq = htonl(ntohl(raw_pktinfo.tcphdr->seq) + 1); - replay_pktinfo.tcphdr->window = htons(value->window); - replay_pktinfo.tcphdr->check = 0; - replay_pktinfo.tcphdr->check = kni_tcp_checksum_v6((void*)replay_pktinfo.tcphdr, - tot_len - replay_pktinfo.iphdr_len, replay_pktinfo.iphdr.v6->ip6_src, replay_pktinfo.iphdr.v6->ip6_dst); + struct stream_tuple4_v6 key; + kni_addr_trans_v6(&key, key_str, sizeof(key_str)); + tuple2stream_htable_key_get_v6_by_packet(&pktinfo, &key, &reversed); + value = (tuple2stream_htable_value*)MESA_htable_search(handle, (const unsigned char*)(&key), sizeof(key)); } //ipv4 else{ - struct iphdr *raw_packet_iphdr = (struct iphdr*)raw_packet; - tot_len = ntohs(raw_packet_iphdr->tot_len); - uint16_t iphdr_len = raw_packet_iphdr->ihl * 4; - struct tcphdr *raw_packet_tcphdr = (struct tcphdr*)((char*)raw_packet_iphdr + iphdr_len); - //replay packet - replay_packet = ALLOC(char, tot_len); - memcpy(replay_packet, raw_packet, tot_len); - struct iphdr *replay_packet_iphdr = (struct iphdr*)replay_packet; - struct tcphdr *replay_packet_tcphdr = (struct tcphdr*)((char*)replay_packet_iphdr + iphdr_len); - replay_packet_iphdr->saddr = raw_packet_iphdr->daddr; - replay_packet_iphdr->daddr = raw_packet_iphdr->saddr; - replay_packet_tcphdr->source = raw_packet_tcphdr->dest; - replay_packet_tcphdr->dest = raw_packet_tcphdr->source; - replay_packet_tcphdr->seq = htonl(ntohl(raw_packet_tcphdr->ack_seq) + value->first_data_len); //seq = ack + first_data_len - replay_packet_tcphdr->ack_seq = htonl(ntohl(raw_packet_tcphdr->seq) + 1); //ack = seq + 1 - replay_packet_tcphdr->window = htons(value->window); - replay_packet_iphdr->check = 0; - replay_packet_iphdr->check = kni_ip_checksum((void*)replay_packet_iphdr, iphdr_len); - replay_packet_tcphdr->check = 0; - replay_packet_tcphdr->check = kni_tcp_checksum((void*)replay_packet_tcphdr, tot_len - iphdr_len, - replay_packet_iphdr->saddr, replay_packet_iphdr->daddr); + ret = kni_ipv4_header_parse(raw_packet, &pktinfo); + if(ret < 0){ + char *errmsg = kni_ipv4_errmsg_get((enum kni_ipv4hdr_parse_error)ret); + KNI_LOG_ERROR(logger, "failed at parse ipv4 header, errmsg = %s", errmsg); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV4HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); + return -1; + } + struct stream_tuple4_v4 key; + kni_addr_trans_v4(&key, key_str, sizeof(key_str)); + tuple2stream_htable_key_get_v4_by_packet(&pktinfo, &key, &reversed); + value = (tuple2stream_htable_value*)MESA_htable_search(handle, (const unsigned char*)(&key), sizeof(key)); } - //send to tfe: thread_seq = g_iThreadNum - int ret = send_to_tfe(marsio_handle, replay_packet, tot_len, g_iThreadNum + thread_seq, tfe_id, args->addr_type); + if(value == NULL){ + KNI_LOG_ERROR(logger, "MESA_htable: failed at search, key = %s", key_str); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_FAIL], 0, FS_OP_ADD, 1); + return -1; + } + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_SUCC], 0, FS_OP_ADD, 1); + unsigned char dir = value->stream->routedir; + if(reversed == value->reversed){ + dir = MESA_dir_reverse(value->stream->routedir); + } + ret = sapp_inject_pkt(value->stream, SIO_EXCLUDE_THIS_LAYER_HDR, raw_packet, pktinfo.ip_totlen, dir); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at send keepalive replay packet to tfe"); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1); + KNI_LOG_ERROR(logger, "Failed at sapp_inject_pkt, stream addr = %s", key_str); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SAPP_INJECT_FAIL], 0, FS_OP_ADD, 1); + return -1; + } + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SAPP_INJECT_SUCC], 0, FS_OP_ADD, 1); + //add to dabloom + if(g_kni_handle->dup_traffic_switch == 1){ + if(value->pmeinfo->has_dup_traffic == 1){ + ret = dabloom_add(&pktinfo, thread_seq); + if(ret < 0){ + return -1; + } + } } - value->has_replayed = 1; - marsio_buff_free(marsio_handle->instance, &rx_buff, 1, 0, 0); - FREE(&replay_packet); return 0; -} - -void keepalive_replay_htable_search(struct kni_marsio_handle *marsio_handle, marsio_buff_t **rx_buffs, int nr_recv, int tfe_id, int thread_seq){ - void *logger = g_kni_handle->local_logger; - for(int i = 0; i < nr_recv; i++){ - struct ethhdr *ether_hdr = (struct ethhdr*)marsio_buff_mtod(rx_buffs[i]); - if(ether_hdr->h_proto == htons(ETH_P_IP) || ether_hdr->h_proto == htons(ETH_P_IPV6)){ - void *raw_packet = (char*)ether_hdr + sizeof(*ether_hdr); - long cb_ret = -1; - keepalive_replay_search_cb_args cb_args; - memset(&cb_args, 0, sizeof(cb_args)); - cb_args.rx_buff = rx_buffs[i]; - cb_args.marsio_handle = marsio_handle; - cb_args.tfe_id = tfe_id; - cb_args.thread_seq = thread_seq; - //ipv4 - if(ether_hdr->h_proto == htons(ETH_P_IP)){ - struct iphdr *iphdr = (struct iphdr*)raw_packet; - uint16_t iphdr_len = iphdr->ihl * 4; - struct tcphdr *tcphdr = (struct tcphdr*)((char*)iphdr + iphdr_len); - struct stream_tuple4_v4 key; - key.saddr = iphdr->saddr; - key.daddr = iphdr->daddr; - key.source = tcphdr->source; - key.dest = tcphdr->dest; - cb_args.addr_type = ADDR_TYPE_IPV4; - cb_args.raw_packet = raw_packet; - MESA_htable_search_cb(g_kni_handle->keepalive_replay_htable, (const unsigned char *)(&key), - sizeof(key), keepalive_replay_search_cb, &cb_args, &cb_ret); - } - //ipv6 - else{ - void *a_packet = (char*)ether_hdr + sizeof(*ether_hdr); - struct pkt_info pktinfo; - int ret = kni_ipv6_header_parse(a_packet, &pktinfo); - if(ret < 0){ - char *errmsg = kni_ipv6_errmsg_get((enum kni_ipv6hdr_parse_error)ret); - KNI_LOG_ERROR(logger, "Failed at parse ipv6 header, send to vxlan, errmsg is %s", errmsg); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); - sendto_vxlan(rx_buffs[i], marsio_handle->dev_vxlan_sendpath, thread_seq); - } - else{ - struct stream_tuple4_v6 key; - memcpy(key.saddr, &(pktinfo.iphdr.v6->ip6_src), sizeof(*(key.saddr))); - memcpy(key.daddr, &(pktinfo.iphdr.v6->ip6_dst), sizeof(*(key.daddr))); - key.source = pktinfo.tcphdr->source; - key.dest = pktinfo.tcphdr->dest; - cb_args.addr_type = ADDR_TYPE_IPV6; - cb_args.raw_packet = raw_packet; - MESA_htable_search_cb(g_kni_handle->keepalive_replay_htable, (const unsigned char *)(&key), - sizeof(key), keepalive_replay_search_cb, &cb_args, &cb_ret); - } - } - } - else{ - sendto_vxlan(rx_buffs[i], marsio_handle->dev_vxlan_sendpath, thread_seq); - } - } } -static void* thread_tfe_data_receiver(void *args){ - struct thread_tfe_data_receiver_args *_args = (struct thread_tfe_data_receiver_args*)args; - struct kni_marsio_handle *marsio_handle = _args->marsio_handle; - int thread_seq = _args->thread_seq; - FREE(&args); - while(true){ - //polling tfe - for(int i = 0; i < marsio_handle->tfe_enabled_node_count; i++){ - marsio_buff_t *rx_buffs[BURST_MAX]; - int nr_burst = 1; - struct mr_vdev *dev_eth_handler = marsio_handle->tfe_enabled_nodes[i].dev_eth_handler; - int tfe_id = marsio_handle->tfe_enabled_nodes[i].tfe_id; - //receive from tfe, nr_recv <= nr_burst <= BURST_MAX - int nr_recv = marsio_recv_burst(dev_eth_handler, thread_seq, rx_buffs, nr_burst); - if(nr_recv <= 0){ - continue; - } - if(g_kni_handle->keepalive_replay_switch == 1){ - keepalive_replay_htable_search(marsio_handle, rx_buffs, nr_recv, tfe_id, thread_seq); - } - else{ - for(int j = 0; j < nr_recv; j++){ - sendto_vxlan(rx_buffs[j], marsio_handle->dev_vxlan_sendpath, thread_seq); - } - } +extern "C" char kni_polling_all_entry(const struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){ + MESA_htable_handle tuple2stream_htable = g_kni_handle->threads_handle[thread_seq].tuple2stream_htable; + //polling tfe + for(int i = 0; i < g_kni_handle->marsio_handle->tfe_enabled_node_count; i++){ + marsio_buff_t *rx_buffs[BURST_MAX]; + int nr_burst = 1; + struct mr_vdev *dev_eth_handler = g_kni_handle->marsio_handle->tfe_enabled_nodes[i].dev_eth_handler; + //receive from tfe, nr_recv <= nr_burst <= BURST_MAX + int nr_recv = marsio_recv_burst(dev_eth_handler, thread_seq, rx_buffs, nr_burst); + if(nr_recv <= 0){ + continue; + } + for(int j = 0; j < nr_recv; j++){ + struct ethhdr *ether_hdr = (struct ethhdr*)marsio_buff_mtod(rx_buffs[i]); + tuple2stream_htable_search(tuple2stream_htable, ether_hdr, thread_seq); } } - return NULL; + return 0; } @@ -1391,13 +1479,13 @@ static int wrapped_kni_cmsg_get(struct pme_info *pmeinfo, struct kni_cmsg *cmsg, int ret = kni_cmsg_get(cmsg, type, &value_size, &value); if(ret < 0){ if(ret == KNI_CMSG_INVALID_TYPE){ - KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type is %d, ret is %d, stream traceid is %s", + KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type = %d, ret = %d, stream traceid = %s", type, ret, pmeinfo->stream_traceid); } return -1; } if(value_size > value_size_max){ - KNI_LOG_ERROR(logger, "kni_cmsg_get: type is %d, size is %d, which should <= %d, stream traceid is %s", + KNI_LOG_ERROR(logger, "kni_cmsg_get: type = %d, size = %d, which should <= %d, stream traceid = %s", type, value_size, value_size_max, pmeinfo->stream_traceid); return -1; } @@ -1449,11 +1537,11 @@ static long traceid2pme_htable_search_cb(void *data, const uchar *key, uint size wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_CERT_VERIFY, sizeof(pmeinfo->ssl_cert_verify), logger); wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_ERROR, sizeof(pmeinfo->ssl_error), logger); clock_gettime(CLOCK_REALTIME, &(pmeinfo->end_time)); - KNI_LOG_DEBUG(logger, "recv cmsg from tfe, stream traceid is %s", pmeinfo->stream_traceid); + KNI_LOG_DEBUG(logger, "recv cmsg from tfe, stream traceid = %s", pmeinfo->stream_traceid); can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_TFE); if(can_destroy == 1){ traceid2pme_htable_del(pmeinfo); - stream_destroy(pmeinfo); + stream_destroy(pmeinfo, pmeinfo->do_log); } } kni_cmsg_destroy(cmsg); @@ -1473,12 +1561,12 @@ static void* thread_tfe_cmsg_receiver(void *args){ struct sockaddr_in server_addr, client_addr; int ret = MESA_load_profile_string_nodef(profile, section, "listen_eth", listen_eth, sizeof(listen_eth)); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: listen_eth not set, profile is %s, section is %s", profile, section); + KNI_LOG_ERROR(logger, "MESA_prof_load: listen_eth not set, profile = %s, section = %s", profile, section); goto error_out; } ret = MESA_load_profile_int_nodef(profile, section, "listen_port", &listen_port); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: listen_port not set, profile is %s, section is %s", profile, section); + KNI_LOG_ERROR(logger, "MESA_prof_load: listen_port not set, profile = %s, section = %s", profile, section); goto error_out; } KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n listen_eth: %s\n listen_port: %d", @@ -1487,14 +1575,14 @@ static void* thread_tfe_cmsg_receiver(void *args){ //create socket sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd < 0){ - KNI_LOG_ERROR(logger, "Failed at create udp socket, errno is %d, %s", errno, strerror(errno)); + KNI_LOG_ERROR(logger, "Failed at create udp socket, errno = %d, %s", errno, strerror(errno)); goto error_out; } memset(&server_addr, 0, sizeof(server_addr)); memset(&client_addr, 0, sizeof(client_addr)); ret = kni_ipv4_addr_get_by_eth(listen_eth, &listen_ip); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at get bind ipv4 addr, eth is %s", listen_eth); + KNI_LOG_ERROR(logger, "Failed at get bind ipv4 addr, eth = %s", listen_eth); goto error_out; } server_addr.sin_family = AF_INET; // IPv4 @@ -1503,7 +1591,7 @@ static void* thread_tfe_cmsg_receiver(void *args){ //bind ret = bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr)); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at bind udp socket, errno is %d, %s", errno, strerror(errno)); + KNI_LOG_ERROR(logger, "Failed at bind udp socket, errno = %d, %s", errno, strerror(errno)); goto error_out; } //receive @@ -1512,14 +1600,14 @@ static void* thread_tfe_cmsg_receiver(void *args){ int recv_len = recvfrom(sockfd, (char *)buff, sizeof(buff), MSG_WAITALL, (struct sockaddr*)&client_addr, &client_len); if(recv_len < 0){ - KNI_LOG_ERROR(logger, "Failed at recv udp data, errno is %d, %s", errno, strerror(errno)); + KNI_LOG_ERROR(logger, "Failed at recv udp data, errno = %d, %s", errno, strerror(errno)); continue; } - //KNI_LOG_DEBUG(logger, "recv udp data: recv_len is %d\n", recv_len); + //KNI_LOG_DEBUG(logger, "recv udp data: recv_len = %d\n", recv_len); struct kni_cmsg *cmsg = NULL; ret = kni_cmsg_deserialize((const unsigned char*)buff, recv_len, &cmsg); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at deserialize cmsg, ret is %d", ret); + KNI_LOG_ERROR(logger, "Failed at deserialize cmsg, ret = %d", ret); continue; } //get stream_traceid @@ -1527,7 +1615,7 @@ static void* thread_tfe_cmsg_receiver(void *args){ uint16_t value_size; ret = kni_cmsg_get(cmsg, TFE_CMSG_STREAM_TRACE_ID, &value_size, &stream_traceid); if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type is %d, ret is %d", TFE_CMSG_STREAM_TRACE_ID, ret); + KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type = %d, ret = %d", TFE_CMSG_STREAM_TRACE_ID, ret); continue; } //get pme @@ -1552,34 +1640,26 @@ static struct kni_marsio_handle* kni_marsio_init(const char* profile, int tfe_no void *logger = g_kni_handle->local_logger; const char* section = "marsio"; char appsym[KNI_SYMBOL_MAX]; - char dev_vxlan_symbol[KNI_SYMBOL_MAX]; char src_mac_addr_str[KNI_SYMBOL_MAX]; unsigned int opt_value = 1; int tfe_node_enabled; struct mr_instance *mr_inst = NULL; - struct mr_vdev *dev_vxlan_handler = NULL; - struct mr_sendpath *dev_vxlan_sendpath = NULL; struct mr_vdev *dev_eth_handler = NULL; struct mr_sendpath *dev_eth_sendpath = NULL; struct kni_marsio_handle *handle = NULL; int j; int ret = MESA_load_profile_string_nodef(profile, section, "appsym", appsym, sizeof(appsym)); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: appsym not set, profile is %s, section is %s", profile, section); - goto error_out; - } - ret = MESA_load_profile_string_nodef(profile, section, "dev_vxlan_symbol", dev_vxlan_symbol, sizeof(dev_vxlan_symbol)); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: dev_vxlan_symbol not set, profile is %s, section is %s", profile, section); + KNI_LOG_ERROR(logger, "MESA_prof_load: appsym not set, profile = %s, section = %s", profile, section); goto error_out; } ret = MESA_load_profile_string_nodef(profile, section, "src_mac_addr", src_mac_addr_str, sizeof(src_mac_addr_str)); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: src_mac_addr not set, profile is %s, section is %s", profile, section); + KNI_LOG_ERROR(logger, "MESA_prof_load: src_mac_addr not set, profile = %s, section = %s", profile, section); goto error_out; } - KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n appsym: %s\n dev_vxlan_symbol: %s\n src_mac_addr: %s", - section, appsym, dev_vxlan_symbol, src_mac_addr_str); + KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n appsym: %s\n src_mac_addr: %s", + section, appsym, src_mac_addr_str); mr_inst = marsio_create(); if(mr_inst == NULL){ KNI_LOG_ERROR(logger, "Failed at create marsio instance"); @@ -1592,7 +1672,7 @@ static struct kni_marsio_handle* kni_marsio_init(const char* profile, int tfe_no &(handle->src_mac_addr[2]), &(handle->src_mac_addr[3]), &(handle->src_mac_addr[4]), &(handle->src_mac_addr[5])); if(ret != 6){ - KNI_LOG_ERROR(logger, "MESA_prof_load: src_mac_addr is invalid, ret is %d, profile is %s, section is %s", ret, profile, section); + KNI_LOG_ERROR(logger, "MESA_prof_load: src_mac_addr = invalid, ret = %d, profile = %s, section = %s", ret, profile, section); goto error_out; } marsio_option_set(mr_inst, MARSIO_OPT_EXIT_WHEN_ERR, &opt_value, sizeof(opt_value)); @@ -1610,7 +1690,7 @@ static struct kni_marsio_handle* kni_marsio_init(const char* profile, int tfe_no } int ret = MESA_load_profile_string_nodef(profile, _section, "mac_addr", mac_addr_str, sizeof(mac_addr_str)); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: mac_addr not set, profile is %s, section is %s", profile, _section); + KNI_LOG_ERROR(logger, "MESA_prof_load: mac_addr not set, profile = %s, section = %s", profile, _section); goto error_out; } struct tfe_enabled_node tfe_node; @@ -1621,26 +1701,26 @@ static struct kni_marsio_handle* kni_marsio_init(const char* profile, int tfe_no &(tfe_node.mac_addr[2]), &(tfe_node.mac_addr[3]), &(tfe_node.mac_addr[4]), &(tfe_node.mac_addr[5])); if(ret != 6){ - KNI_LOG_ERROR(logger, "MESA_prof_load: mac_addr is invalid, ret is %d, profile is %s, section is %s", ret, profile, _section); + KNI_LOG_ERROR(logger, "MESA_prof_load: mac_addr = invalid, ret = %d, profile = %s, section = %s", ret, profile, _section); goto error_out; } ret = MESA_load_profile_string_nodef(profile, _section, "dev_eth_symbol", dev_eth_symbol, sizeof(dev_eth_symbol)); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: dev_eth_symbol not set, profile is %s, section is %s", profile, _section); + KNI_LOG_ERROR(logger, "MESA_prof_load: dev_eth_symbol not set, profile = %s, section = %s", profile, _section); goto error_out; } KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n enabled: %d, mac_addr: %s\n dev_eth_symbol: %s", _section, tfe_node_enabled, mac_addr_str, dev_eth_symbol); - //eth_handler receive thread = tfe_data_recv_thread_num, send thread = g_iThreadNum + tfe_data_recv_thread_num - dev_eth_handler = marsio_open_device(mr_inst, dev_eth_symbol, g_kni_handle->tfe_data_recv_thread_num, g_iThreadNum + g_kni_handle->tfe_data_recv_thread_num); + //eth_handler receive thread = thread_count, send thread = thread_count + dev_eth_handler = marsio_open_device(mr_inst, dev_eth_symbol, g_kni_handle->thread_count, g_kni_handle->thread_count); if(dev_eth_handler == NULL){ - KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol is %s", dev_eth_symbol); + KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol = %s", dev_eth_symbol); goto error_out; } //sendpath dev_eth_sendpath = marsio_sendpath_create_by_vdev(dev_eth_handler); if(dev_eth_sendpath == NULL){ - KNI_LOG_ERROR(logger, "Failed at create marsio sendpath, dev_symbol is %s", dev_eth_symbol); + KNI_LOG_ERROR(logger, "Failed at create marsio sendpath, dev_symbol = %s", dev_eth_symbol); goto error_out; } //tfe_node @@ -1650,20 +1730,6 @@ static struct kni_marsio_handle* kni_marsio_init(const char* profile, int tfe_no handle->tfe_enabled_nodes[j++] = tfe_node; } handle->tfe_enabled_node_count = j; - //vxlan_handler: receive: 0, send: tfe_data_recv_thread_num - dev_vxlan_handler = marsio_open_device(mr_inst, dev_vxlan_symbol, 0, g_kni_handle->tfe_data_recv_thread_num); - if(dev_vxlan_handler == NULL){ - KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol is %s", dev_vxlan_symbol); - goto error_out; - } - handle->dev_vxlan_handler = dev_vxlan_handler; - //vxlan sendpath - dev_vxlan_sendpath = marsio_sendpath_create_by_vdev(dev_vxlan_handler); - if(dev_eth_sendpath == NULL){ - KNI_LOG_ERROR(logger, "Failed at create marsio sendpath, dev_symbol is %s", dev_vxlan_symbol); - goto error_out; - } - handle->dev_vxlan_sendpath = dev_vxlan_sendpath; //marsio_thread_init(mr_instance); return handle; @@ -1689,7 +1755,7 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ int value = 0; int ret = MESA_load_profile_string_nodef(profile, section, "stat_path", stat_path, sizeof(stat_path)); if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: stat_path not set, profile is %s, section is %s", profile, section); + KNI_LOG_ERROR(logger, "MESA_prof_load: stat_path not set, profile = %s, section = %s", profile, section); goto error_out; } KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n stat_path: %s\n", "field_stat", stat_path); @@ -1716,52 +1782,73 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ fs_handle->handle = handle; fs_handle->fields[KNI_FIELD_INTCP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_stm"); fs_handle->fields[KNI_FIELD_BYP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_stm"); - fs_handle->fields[KNI_FIELD_POLICY_BYP] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "policy_byp"); - fs_handle->fields[KNI_FIELD_PME_NEW_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "pme_new_fail"); - fs_handle->fields[KNI_FIELD_NO_TFE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "no_tfe"); - fs_handle->fields[KNI_FIELD_STATE_UNKNOWN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "state_unknown"); - fs_handle->fields[KNI_FIELD_STM_ERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "stm_err"); + fs_handle->fields[KNI_FIELD_BYP_STM_POLICY] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_policy"); + fs_handle->fields[KNI_FIELD_BYP_STM_PME_NEW_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_pme_new_F"); + fs_handle->fields[KNI_FIELD_BYP_STM_NO_TFE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_no_tfe"); + fs_handle->fields[KNI_FIELD_BYP_STM_ERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_stm_err"); + fs_handle->fields[KNI_FIELD_BYP_STM_DUP_TFC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_dup_tfc"); + fs_handle->fields[KNI_FIELD_STATE_UNKNOWN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "state_unknow"); + fs_handle->fields[KNI_FIELD_DUP_TFC_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dup_tfc_stm"); //stream error - fs_handle->fields[KNI_FIELD_NO_SYN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "no_syn"); - fs_handle->fields[KNI_FIELD_SINGLE_DIR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "single_dir"); - fs_handle->fields[KNI_FIELD_PROTO_UNKNOWN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "proto_unknow"); - fs_handle->fields[KNI_FIELD_NO_SA] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "no_s/a"); - fs_handle->fields[KNI_FIELD_ACTION_INVALID] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "action_invalid"); - fs_handle->fields[KNI_FIELD_NO_DATA] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "no_data"); - fs_handle->fields[KNI_FIELD_IPV4HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "v4_parse_fail"); - fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "v6_parse_fail"); - fs_handle->fields[KNI_FIELD_KA_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ka_add_fail"); - fs_handle->fields[KNI_FIELD_EXCEED_MTU] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "exceed_mtu"); - fs_handle->fields[KNI_FIELD_SENDTO_TFE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sendtfe_fail"); + fs_handle->fields[KNI_FIELD_NO_SYN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_no_syn"); + fs_handle->fields[KNI_FIELD_SINGLE_DIR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_sig_dir"); + fs_handle->fields[KNI_FIELD_PROTO_UNKNOWN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_pro_unknow"); + fs_handle->fields[KNI_FIELD_NO_SA] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_no_s/a"); + fs_handle->fields[KNI_FIELD_ACTION_INVALID] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_act_invaid"); + fs_handle->fields[KNI_FIELD_NO_DATA] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_no_data"); + fs_handle->fields[KNI_FIELD_IPV4HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_v4_parse"); + fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_v6_parse"); + fs_handle->fields[KNI_FIELD_EXCEED_MTU] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_exced_mtu"); + fs_handle->fields[KNI_FIELD_SENDTO_TFE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "err_sdtfe_F"); + fs_handle->fields[KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "errTup2stmAddF"); //others fs_handle->fields[KNI_FIELD_NULL_PKT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "null_pkt"); fs_handle->fields[KNI_FIELD_IPV4_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv4_stm"); fs_handle->fields[KNI_FIELD_IPV6_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv6_stm"); fs_handle->fields[KNI_FIELD_SSL_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ssl_stm"); fs_handle->fields[KNI_FIELD_HTTP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "http_stm"); - fs_handle->fields[KNI_FIELD_SENDLOG_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sendlog_succ"); - fs_handle->fields[KNI_FIELD_SENDLOG_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sendlog_fail"); + fs_handle->fields[KNI_FIELD_SENDLOG_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sendlog_S"); + fs_handle->fields[KNI_FIELD_SENDLOG_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sendlog_F"); fs_handle->fields[KNI_FIELD_PME_NEW_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "pme_new"); fs_handle->fields[KNI_FIELD_PME_FREE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "pme_free"); //intercept traffic stat - fs_handle->fields[KNI_FIELD_KNI_INTCP_BYTES] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kni_intcp_bytes"); - fs_handle->fields[KNI_FIELD_TFE_INTCP_BYTES] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tfe_intcp_bytes"); + fs_handle->fields[KNI_FIELD_KNI_INTCP_BYTES] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kni_intcp_B"); + fs_handle->fields[KNI_FIELD_TFE_INTCP_BYTES] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tfe_intcp_B"); fs_handle->fields[KNI_FIELD_KNI_INTCP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kni_intcp_stm"); fs_handle->fields[KNI_FIELD_TFE_INTCP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tfe_intcp_stm"); //htable - fs_handle->fields[KNI_FIELD_ID2PME_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_add_succ"); - fs_handle->fields[KNI_FIELD_ID2PME_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_add_fail"); - fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_del_succ"); - fs_handle->fields[KNI_FIELD_ID2PME_DEL_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_del_fail"); - fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ka_add_succ"); - fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_DEL_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ka_del_fail"); - fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ka_del_succ"); + fs_handle->fields[KNI_FIELD_ID2PME_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_add_S"); + fs_handle->fields[KNI_FIELD_ID2PME_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_add_F"); + fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_del_S"); + fs_handle->fields[KNI_FIELD_ID2PME_DEL_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_del_F"); + fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_add_S"); + fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_add_F"); + fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_del_S"); + fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_del_F"); + fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_srch_S"); + fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_srch_F"); + fs_handle->fields[KNI_FIELD_SAPP_INJECT_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sapp_inject_S"); + fs_handle->fields[KNI_FIELD_SAPP_INJECT_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sapp_inject_F"); + fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "bloom_srch_S"); + fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "bloom_srch_F"); + fs_handle->fields[KNI_FIELD_BLOOM_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "bloom_add_S"); + fs_handle->fields[KNI_FIELD_BLOOM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "bloom_add_F"); for(int i = 0; i < g_kni_handle->marsio_handle->tfe_enabled_node_count; i++){ int tfe_id = g_kni_handle->marsio_handle->tfe_enabled_nodes[i].tfe_id; char tfe_status[KNI_SYMBOL_MAX] = ""; snprintf(tfe_status, sizeof(tfe_status), "tfe%d", tfe_id); fs_handle->fields[KNI_FIELD_TFE_STATUS_BASE + i] = FS_register(handle, FS_STYLE_STATUS, FS_CALC_CURRENT, tfe_status); } + //table + fs_handle->column_cnt = g_kni_handle->thread_count; + char buff[KNI_PATH_MAX]; + for(int i = 0; i < fs_handle->column_cnt; i++){ + snprintf(buff, sizeof(buff), "tid%d", i); + fs_handle->column_ids[i] = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_SPEED, buff); + } + snprintf(buff, sizeof(buff), "bloom_cnt"); + fs_handle->line_ids[0] = FS_register(handle, FS_STYLE_LINE, FS_CALC_SPEED, buff); + fs_handle->handle = handle; FS_start(handle); return fs_handle; @@ -1789,26 +1876,55 @@ static int traceid2pme_htable_expire_notify_cb(void *data, int eliminate_type){ can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_TFE); if(can_destroy == 1){ FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC], 0, FS_OP_ADD, 1); - stream_destroy(pmeinfo); + stream_destroy(pmeinfo, pmeinfo->do_log); return 1; } } return 0; } -static void keepalive_replay_data_free_cb(void *data) -{ - FREE(&data); +static void tuple2stream_htable_data_free_cb(void *data){ + FREE(&data); +} + +int dup_traffic_dabloom_init(const char *profile, void *logger){ + const char *section = "dup_traffic"; + MESA_load_profile_int_def(profile, section, "switch", &(g_kni_handle->dup_traffic_switch), 0); + KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n switch: %d", g_kni_handle->dup_traffic_switch); + if(g_kni_handle->dup_traffic_switch == 1){ + unsigned int capacity = 0; + char error_rate_str[KNI_SYMBOL_MAX]; + double error_rate = 0.05; + int expiry_time = 0; + MESA_load_profile_int_def(profile, section, "action", &(g_kni_handle->dup_traffic_action), KNI_ACTION_BYPASS); + MESA_load_profile_uint_def(profile, section, "capacity", &capacity, 1000000); + MESA_load_profile_string_def(profile, section, "error_rate", error_rate_str, sizeof(error_rate_str), "0.05"); + MESA_load_profile_int_def(profile, section, "expiry_time", &expiry_time, 30); + KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n action: %d\n capacity: %d\n error_rate: %s\n expiry_time: %d", + section, capacity, error_rate_str, expiry_time); + error_rate = atof(error_rate_str); + for(int i = 0; i < g_kni_handle->thread_count; i++){ + struct expiry_dablooms_handle* dabloom_handle = expiry_dablooms_init(capacity, error_rate, expiry_time); + if(dabloom_handle == NULL){ + KNI_LOG_ERROR(logger, "Failed at expiry_dablooms_init, capacity = %d," + "error_rate = %lf, expire_time = %d", capacity, error_rate, expiry_time); + return -1; + } + g_kni_handle->threads_handle[i].dabloom_handle = dabloom_handle; + } + return 0; + } + return 0; } extern "C" int kni_init(){ char *kni_git_verison = (char*)KNI_GIT_VERSION; - const char *profile = "./conf/kni/kni.conf"; + const char *profile = "./etc/kni/kni.conf"; const char *section = "global"; + //init logger char log_path[KNI_PATH_MAX] = ""; int tfe_node_count = 0; - int tfe_data_recv_thread_num = -1; char manage_eth[KNI_SYMBOL_MAX] = ""; struct kni_send_logger *send_logger = NULL; struct kni_field_stat_handle *fs_handle = NULL; @@ -1816,18 +1932,17 @@ extern "C" int kni_init(){ void *local_logger = NULL; int log_level = -1; pthread_t thread_id = -1; - int keepalive_replay_switch = -1; struct thread_tfe_cmsg_receiver_args *cmsg_receiver_args; - MESA_htable_handle traceid2pme_htable = NULL, keepalive_replay_htable = NULL; + MESA_htable_handle traceid2pme_htable = NULL; struct tfe_mgr *_tfe_mgr = NULL; int ret = MESA_load_profile_string_nodef(profile, section, "log_path", log_path, sizeof(log_path)); if(ret < 0){ - printf("MESA_prof_load: log_path not set, profile is %s, section is %s", profile, section); + printf("MESA_prof_load: log_path not set, profile = %s, section = %s", profile, section); goto error_out; } ret = MESA_load_profile_int_nodef(profile, section, "log_level", &log_level); if(ret < 0){ - printf("MESA_prof_load: log_level not set, profile is %s, section is %s", profile, section); + printf("MESA_prof_load: log_level not set, profile = %s, section = %s", profile, section); goto error_out; } local_logger = MESA_create_runtime_log_handle(log_path, log_level); @@ -1836,45 +1951,47 @@ extern "C" int kni_init(){ goto error_out; } //kni_git_log - KNI_LOG_ERROR(local_logger, "----------kni version is %s-----------", kni_git_verison); + KNI_LOG_ERROR(local_logger, "----------kni version = %s-----------", kni_git_verison); ret = MESA_load_profile_int_nodef(profile, section, "tfe_node_count", &tfe_node_count); if(ret < 0){ - KNI_LOG_ERROR(local_logger, "MESA_prof_load: tfe_node_count not set, profile is %s, section is %s", profile, section); + KNI_LOG_ERROR(local_logger, "MESA_prof_load: tfe_node_count not set, profile = %s, section = %s", profile, section); goto error_out; } if(tfe_node_count > TFE_COUNT_MAX){ - KNI_LOG_ERROR(local_logger, "tfe_node_count is %d, exceed the max_tfe_node_count %d", tfe_node_count, TFE_COUNT_MAX); + KNI_LOG_ERROR(local_logger, "tfe_node_count = %d, exceed the max_tfe_node_count %d", tfe_node_count, TFE_COUNT_MAX); goto error_out; } if(tfe_node_count <= 0){ - KNI_LOG_ERROR(local_logger, "tfe_node_count is %d, <= 0", tfe_node_count); + KNI_LOG_ERROR(local_logger, "tfe_node_count = %d, <= 0", tfe_node_count); goto error_out; } - ret = MESA_load_profile_int_def(profile, section, "tfe_data_recv_thread_num", &tfe_data_recv_thread_num, 1); ret = MESA_load_profile_string_nodef(profile, section, "manage_eth", manage_eth, sizeof(manage_eth)); if(ret < 0){ - printf("MESA_prof_load: manage_eth not set, profile is %s, section is %s", profile, section); + printf("MESA_prof_load: manage_eth not set, profile = %s, section = %s", profile, section); goto error_out; } - ret = MESA_load_profile_int_def(profile, section, "keepalive_replay_switch", &keepalive_replay_switch, 1); - KNI_LOG_ERROR(local_logger, "MESA_prof_load, [%s]:\n log_path: %s\n log_level: %d\n tfe_node_count: %d\n" - "tfe_data_recv_thread_num: %d\n manage_eth: %s\n keepalive_replay_switch: %d", - section, log_path, log_level, tfe_node_count, tfe_data_recv_thread_num, manage_eth, keepalive_replay_switch); + KNI_LOG_ERROR(local_logger, "MESA_prof_load, [%s]:\n log_path: %s\n log_level: %d\n tfe_node_count: %d\n manage_eth: %s", + section, log_path, log_level, tfe_node_count, manage_eth); g_kni_handle = ALLOC(struct kni_handle, 1); g_kni_handle->local_logger = local_logger; - g_kni_handle->tfe_data_recv_thread_num = tfe_data_recv_thread_num; - g_kni_handle->keepalive_replay_switch = keepalive_replay_switch; //init http_project id = http_project_init(); if(id < 0){ - KNI_LOG_ERROR(local_logger, "Failed at init http project, ret is %d", id); + KNI_LOG_ERROR(local_logger, "Failed at init http project, ret = %d", id); goto error_out; } g_kni_handle->http_project_id = id; + // get thread count + g_kni_handle->thread_count = get_thread_count(); + if(g_kni_handle->thread_count <= 0){ + KNI_LOG_ERROR(local_logger, "Failed at get_thread_count, ret = %d"); + goto error_out; + } + //init marsio g_kni_handle->marsio_handle = kni_marsio_init(profile, tfe_node_count); if(g_kni_handle->marsio_handle == NULL){ @@ -1883,7 +2000,7 @@ extern "C" int kni_init(){ } //init maat - g_kni_handle->maat_handle = kni_maat_init(profile, local_logger); + g_kni_handle->maat_handle = kni_maat_init(profile, local_logger, g_kni_handle->thread_count); if(g_kni_handle->maat_handle == NULL){ KNI_LOG_ERROR(local_logger, "Failed at init maat"); goto error_out; @@ -1900,7 +2017,7 @@ extern "C" int kni_init(){ //init local_ipv4 ret = kni_ipv4_addr_get_by_eth(manage_eth, &(g_kni_handle->local_ipv4)); if(ret < 0){ - KNI_LOG_ERROR(local_logger, "Failed at get bind ipv4 addr, eth is %s", manage_eth); + KNI_LOG_ERROR(local_logger, "Failed at get bind ipv4 addr, eth = %s", manage_eth); goto error_out; } @@ -1921,15 +2038,22 @@ extern "C" int kni_init(){ } g_kni_handle->traceid2pme_htable = traceid2pme_htable; - //init keepalive_replay_htable - if(g_kni_handle->keepalive_replay_switch == 1){ - keepalive_replay_htable = kni_create_htable(profile, "keepalive_replay_htable", (void*)keepalive_replay_data_free_cb, - NULL, local_logger); - if(keepalive_replay_htable == NULL){ - KNI_LOG_ERROR(local_logger, "Failed at create keepalive_replay_htable"); + //init tuple2stream_htable + g_kni_handle->threads_handle = ALLOC(struct per_thread_handle, g_kni_handle->thread_count); + for(int i = 0; i < g_kni_handle->thread_count; i++){ + MESA_htable_handle tuple2stream_htable = kni_create_htable(profile, "tuple2stream_htable", + (void*)tuple2stream_htable_data_free_cb, NULL, local_logger); + if(tuple2stream_htable == NULL){ + KNI_LOG_ERROR(local_logger, "Failed at kni_create_htable, table = tuple2stream_htable"); goto error_out; } - g_kni_handle->keepalive_replay_htable = keepalive_replay_htable; + g_kni_handle->threads_handle[i].tuple2stream_htable = tuple2stream_htable; + } + + //init dabloom_handle + ret = dup_traffic_dabloom_init(profile, local_logger); + if(ret < 0){ + goto error_out; } //init tfe_mgr @@ -1940,27 +2064,13 @@ extern "C" int kni_init(){ } g_kni_handle->_tfe_mgr = _tfe_mgr; - //create thread_tfe_data_receiver - for(int i = 0; i < g_kni_handle->tfe_data_recv_thread_num; i++){ - struct thread_tfe_data_receiver_args *args = ALLOC(struct thread_tfe_data_receiver_args, 1); - args->logger = local_logger; - args->marsio_handle = g_kni_handle->marsio_handle; - args->thread_seq = i; - int ret = pthread_create(&thread_id, NULL, thread_tfe_data_receiver, (void *)args); - if(unlikely(ret != 0)){ - KNI_LOG_ERROR(local_logger, "Failed at pthread_create, thread_func is thread_tfe_data_receiver, errno is %d, errmsg is %s", errno, strerror(errno)); - FREE(&args); - goto error_out; - } - } - //create thread_tfe_cmsg_receiver cmsg_receiver_args = ALLOC(struct thread_tfe_cmsg_receiver_args, 1); cmsg_receiver_args->logger = local_logger; strncpy(cmsg_receiver_args->profile, profile, strnlen(profile, sizeof(cmsg_receiver_args->profile) - 1)); ret = pthread_create(&thread_id, NULL, thread_tfe_cmsg_receiver, (void *)cmsg_receiver_args); if(unlikely(ret != 0)){ - KNI_LOG_ERROR(local_logger, "Failed at pthread_create, thread_func is thread_tfe_cmsg_receiver, errno is %d, errmsg is %s", errno, strerror(errno)); + KNI_LOG_ERROR(local_logger, "Failed at pthread_create, thread_func = thread_tfe_cmsg_receiver, errno = %d, errmsg = %s", errno, strerror(errno)); FREE(&cmsg_receiver_args); goto error_out; } diff --git a/entry/src/kni_maat.cpp b/entry/src/kni_maat.cpp index e20de0f..8498227 100644 --- a/entry/src/kni_maat.cpp +++ b/entry/src/kni_maat.cpp @@ -1,8 +1,6 @@ #include "kni_utils.h" #include "kni_maat.h" -extern int g_iThreadNum; - /* default action: 1. read kni.conf @@ -62,7 +60,7 @@ void compile_ex_param_dup(int idx, MAAT_RULE_EX_DATA *to, MAAT_RULE_EX_DATA *fro return; } -struct kni_maat_handle* kni_maat_init(const char* profile, void *logger){ +struct kni_maat_handle* kni_maat_init(const char* profile, void *logger, int thread_count){ const char *section = "maat"; int readconf_mode; char tableinfo_path[KNI_PATH_MAX]; @@ -105,11 +103,11 @@ struct kni_maat_handle* kni_maat_init(const char* profile, void *logger){ KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n readconf_mode: %d\n tableinfo_path: %s\n tablename_intercept_ip: %s\n tablename_intercept_domain: %s\n" "default_action: %d", section, readconf_mode, tableinfo_path, tablename_intercept_ip, tablename_intercept_domain, g_maat_default_action); - feather = Maat_feather(g_iThreadNum, tableinfo_path, logger); + feather = Maat_feather(thread_count, tableinfo_path, logger); handle = ALLOC(struct kni_maat_handle, 1); handle->feather = feather; if(feather == NULL){ - KNI_LOG_ERROR(logger, "Failed at Maat_feather, max_thread_num is %d, tableinfo_path is %s", g_iThreadNum, tableinfo_path); + KNI_LOG_ERROR(logger, "Failed at Maat_feather, max_thread_num is %d, tableinfo_path is %s", thread_count, tableinfo_path); return NULL; } Maat_set_feather_opt(feather, MAAT_OPT_EFFECT_INVERVAL_MS, &effective_interval_ms, sizeof(effective_interval_ms)); diff --git a/entry/src/kni_tap.cpp b/entry/src/kni_tap.cpp new file mode 100644 index 0000000..1301539 --- /dev/null +++ b/entry/src/kni_tap.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include "kni_utils.h" +#include "MESA_prof_load.h" + +struct kni_tap_handle{ + int fd; + void *logger; +}; + +struct kni_tap_handle* kni_tap_init(void *logger){ + struct kni_tap_handle * tap_handle = (struct kni_tap_handle*)malloc(sizeof(struct kni_tap_handle)); + + char tap_path[1024] = "tap"; + char tap_name[IFNAMSIZ] = {0}; + struct ifreq ifr; + int err = 0; + MESA_load_profile_string_def(".kniconf/kni.conf", "tap", (char*)"tap_path", tap_path, 1024, "/dev/net/tap"); + MESA_load_profile_string_def(".kniconf/kni.conf", "tap", (char*)"tap_name", tap_name, 1024, "/dev/net/tap"); + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE; + if(*tap_name){ + strncpy(ifr.ifr_name, tap_name, IFNAMSIZ); + } + if((tap_handle ->fd = open(tap_path, O_RDWR)) < 0){ + KNI_LOG_ERROR(logger, "kni_tap_init():open error,errno is:%d,%s",errno,strerror(errno)); + free(tap_handle); + return NULL; + } + err = ioctl(tap_handle ->fd, TUNSETIFF, (void *)&ifr); + if(err) { + KNI_LOG_ERROR(logger ,"kni_tap_init():ioctl error,errno is:%d,%s",errno,strerror(errno)); + close(tap_handle ->fd); + free(tap_handle); + return NULL; + } + tap_handle->logger = logger; + retrun tap_handle; +} + + +int kni_tap_write(struct kni_tap_handle *handle, char *buff, uint16_t buff_len){ + uint16_t send_len = write(handle->fd, buff, buff_len); + if(send_len < 0){ + KNI_LOG_ERROR(handle->logger, "Failed at kni_tap_write, errno = %d(%s)", errno, strerror(errno)); + return -1; + } + if(send_len < buff_len){ + KNI_LOG_ERROR(handle->logger, "kni_tap_write: need send %dB, only send %dB", buff_len, send_len); + return -2; + } + return 0; +} + +/* +* > 0 : read data length +* = 0 : read null +* = -1 : error +*/ +int kni_tap_read(struct kni_tap_handle *handle, char *buff, uint16_t buff_len){ + int recv_len = 0; + recv_len = read(handle -> fd, buff, buff_len); + if(recv_len < 0){ + KNI_LOG_ERROR(handle -> logger, "kni_tap_read() error %d, %s", errno, strerror(errno)); + return -1; + } + else{ + return recv_len; + } + return 0; +} \ No newline at end of file diff --git a/script/run.sh b/script/run.sh index 4a00283..945a771 100755 --- a/script/run.sh +++ b/script/run.sh @@ -1,11 +1,10 @@ -SAPP_RUN="/home/tsg/kni" -/bin/cp -f ../conf/sapp/conflist_business.inf $SAPP_RUN/plug/business/conflist_business.inf +SAPP_RUN="/home/tsg/sapp_v4" /bin/cp -rf ../conf/sapp/kni/ $SAPP_RUN/plug/business -/bin/cp -f ../build/entry/libkni.so $SAPP_RUN/plug/business/kni/kni2.so +rm -f $SAPP_RUN/plug/business/kni/kni2.so && /bin/cp -f ../build/entry/libkni.so $SAPP_RUN/plug/business/kni/kni2.so -mkdir -p $SAPP_RUN/conf/kni -/bin/cp -f ../conf/kni.conf $SAPP_RUN/conf/kni/kni.conf -/bin/cp -f ../conf/maat/maat_test.json $SAPP_RUN/conf/kni/maat_test.json -/bin/cp -f ../conf/maat/maat_tableinfo.conf $SAPP_RUN/conf/kni/maat_tableinfo.conf -cat $SAPP_RUN/conf/project_list.conf | grep "kni_http_tag" >/dev/null 2>&1 && exit -echo "kni_http_tag struct" >> $SAPP_RUN/conf/project_list.conf \ No newline at end of file +mkdir -p $SAPP_RUN/etc/kni +/bin/cp -f ../conf/kni.conf $SAPP_RUN/etc/kni/kni.conf +/bin/cp -f ../conf/maat/maat_test.json $SAPP_RUN/etc/kni/maat_test.json +/bin/cp -f ../conf/maat/maat_tableinfo.conf $SAPP_RUN/etc/kni/maat_tableinfo.conf +cat $SAPP_RUN/etc/project_list.conf | grep "kni_http_tag" >/dev/null 2>&1 && exit +echo "kni_http_tag struct" >> $SAPP_RUN/etc/project_list.conf \ No newline at end of file diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 8d349aa..fa03335 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -37,7 +37,21 @@ add_dependencies(uuid libUUID) set_property(TARGET uuid PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libuuid.a) set_property(TARGET uuid PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +### dabloom +ExternalProject_Add(dablooms PREFIX dablooms + URL ${CMAKE_CURRENT_SOURCE_DIR}/dablooms-v1.0.0-20190904.tar.gz + URL_MD5 9c49aaf1eefe5e0f836b46fc30287782 + CONFIGURE_COMMAND cd . + BUILD_COMMAND cd ../dablooms && make + INSTALL_COMMAND cd ../dablooms && make install prefix=) +ExternalProject_Get_Property(dablooms INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) + +add_library(dabloom SHARED IMPORTED GLOBAL) +add_dependencies(dabloom dablooms) +set_property(TARGET dabloom PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libdablooms.a) +set_property(TARGET dabloom PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) ### MESA Framework diff --git a/vendor/dablooms-v1.0.0-20190904.tar.gz b/vendor/dablooms-v1.0.0-20190904.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..b2c81da49d677bb2441d1ae5f06f0d095e37199b GIT binary patch literal 19798 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 BK$-vm literal 0 HcmV?d00001