diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 83e9bbe..70def4d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,3 +1,13 @@ -add_library(common STATIC src/kni_utils.cpp src/ssl_utils.cpp) +add_library(common STATIC src/kni_utils.cpp src/ssl_utils.cpp src/kni_cmsg.cpp) target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) -target_link_libraries(common MESA_handle_logger) \ No newline at end of file +target_link_libraries(common MESA_handle_logger) + +### test_cmsg +add_executable(test_cmsg test/test_cmsg.cpp) +target_include_directories(test_cmsg PRIVATE include) +target_link_libraries(test_cmsg PRIVATE common) + +### test_uuid +add_executable(test_uuid test/test_uuid.cpp) +target_include_directories(test_uuid PRIVATE include) +target_link_libraries(test_uuid PRIVATE uuid common) diff --git a/common/include/kni_cmsg.h b/common/include/kni_cmsg.h new file mode 100644 index 0000000..eeab498 --- /dev/null +++ b/common/include/kni_cmsg.h @@ -0,0 +1,48 @@ +#pragma once + +#define KNI_CMSG_TLV_NR_MAX 64 +struct kni_cmsg; +struct kni_cmsg_serialize_header; + + +enum kni_cmsg_errno{ + KNI_CMSG_INVALID_FORMAT = -1, + KNI_CMSG_BUFF_NOT_ENOUGH = -2, + KNI_CMSG_INVALID_TYPE = -3 +}; + +enum tfe_cmsg_tlv_type +{ + /* TCP restore information */ + TFE_CMSG_TCP_RESTORE_SEQ = 0x0, + TFE_CMSG_TCP_RESTORE_ACK = 0x1, + TFE_CMSG_TCP_RESTORE_MSS_CLIENT = 0x2, + TFE_CMSG_TCP_RESTORE_MSS_SERVER = 0x3, + TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT = 0x4, + TFE_CMSG_TCP_RESTORE_WSACLE_SERVER = 0x5, + TFE_CMSG_TCP_RESTORE_SACK_CLIENT = 0x6, + TFE_CMSG_TCP_RESTORE_SACK_SERVER = 0x7, + TFE_CMSG_TCP_RESTORE_TS_CLIENT = 0x8, + TFE_CMSG_TCP_RESTORE_TS_SERVER = 0x9, + TFE_CMSG_TCP_RESTORE_PROTOCOL = 0xa, + + TFE_CMSG_POLICY_ID = 0x10, + TFE_CMSG_STREAM_TRACE_ID = 0x11, + + TFE_CMSG_SSL_INTERCEPT_STATE, //size uint64_t, 0-passthrough, 1-intercept, 2-shutdown, referer from enum ssl_stream_action + TFE_CMSG_SSL_UPSTREAM_LATENCY, //size uint64_t, milisecond + TFE_CMSG_SSL_DOWNSTREAM_LATENCY, //size uint64_t, milisecond + TFE_CMSG_SSL_UPSTREAM_VERSION, //string, SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 unknown + TFE_CMSG_SSL_DOWNSTREAM_VERSION, + TFE_CMSG_SSL_PINNING_STATE, //size uint64_t, 0-not pinning 1-pinning 2-maybe pinning + TFE_CMSG_SSL_CERT_VERIFY, + TFE_CMSG_SSL_ERROR +}; + +struct kni_cmsg* kni_cmsg_init(); +void kni_cmsg_destroy(struct kni_cmsg *cmsg); +int kni_cmsg_get(struct kni_cmsg *cmsg, uint16_t type, uint16_t *size, unsigned char **pvalue); +int kni_cmsg_set(struct kni_cmsg *cmsg, uint16_t type, const unsigned char *value, uint16_t size); +uint16_t kni_cmsg_serialize_size_get(struct kni_cmsg *cmsg); +int kni_cmsg_serialize(struct kni_cmsg *cmsg, unsigned char *buff, uint16_t bufflen, uint16_t *serialize_len); +int kni_cmsg_deserialize(const unsigned char *data, uint16_t len, struct kni_cmsg** pcmsg); diff --git a/common/include/kni_utils.h b/common/include/kni_utils.h index 0bdb946..dc583c8 100644 --- a/common/include/kni_utils.h +++ b/common/include/kni_utils.h @@ -21,6 +21,7 @@ #define KNI_PATH_MAX 256 #define KNI_SYMBOL_MAX 64 #define KNI_DOMAIN_MAX 256 + #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -79,6 +80,8 @@ enum kni_field{ KNI_FIELD_INTCP_STM, KNI_FIELD_SSL_STM, KNI_FIELD_HTTP_STM, + KNI_FIELD_SENDLOG_SUCC, + KNI_FIELD_SENDLOG_FAIL, KNI_FIELD_UNKNOWN_STM, }; @@ -87,10 +90,12 @@ struct kni_field_stat_handle{ int fields[KNI_FIELD_MAX]; }; - +int kni_stream_addr_trans(struct ipaddr* addr, 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_udp_checksum(const void *_buf, size_t len, in_addr_t src_addr, in_addr_t dest_addr); struct kni_tcpopt_info* kni_get_tcpopt(struct tcphdr* tcphdr,int tcphdr_len); +int kni_ipv4_addr_get_by_eth(const char *ifname, uint32_t *ip); + MESA_htable_handle kni_create_htable(const char *profile, const char *section, void *free_data_cb, void *expire_notify_cb, void *logger); \ No newline at end of file diff --git a/common/src/kni_cmsg.cpp b/common/src/kni_cmsg.cpp new file mode 100644 index 0000000..cef096b --- /dev/null +++ b/common/src/kni_cmsg.cpp @@ -0,0 +1,190 @@ +#include "kni_utils.h" +#include "kni_cmsg.h" + +struct kni_cmsg_tlv +{ + uint16_t type; + uint16_t length; + unsigned char value_as_string[0]; +} __attribute__((packed)); + +struct kni_cmsg +{ + uint16_t nr_tlvs; + struct kni_cmsg_tlv* tlvs[KNI_CMSG_TLV_NR_MAX]; + uint16_t size; +} __attribute__((packed)); + +struct kni_cmsg_serialize_header +{ + uint8_t __magic__[2]; /* Must be 0x4d, 0x5a */ + uint16_t nr_tlvs; + struct kni_cmsg_tlv tlvs[0]; +} __attribute__((packed)); + +struct kni_cmsg* kni_cmsg_init() +{ + struct kni_cmsg *cmsg = ALLOC(struct kni_cmsg, 1); + cmsg->size = sizeof(struct kni_cmsg_serialize_header); + return cmsg; +} + +void kni_cmsg_destroy(struct kni_cmsg *cmsg) +{ + if(cmsg != NULL) + { + for(int i = 0; i < KNI_CMSG_TLV_NR_MAX; i++) + { + FREE(&(cmsg->tlvs[i])); + } + } + FREE(&cmsg); +} + +int kni_cmsg_set(struct kni_cmsg *cmsg, uint16_t type, const unsigned char *value, uint16_t size) +{ + if(type >= KNI_CMSG_TLV_NR_MAX) + { + return KNI_CMSG_INVALID_TYPE; + } + struct kni_cmsg_tlv *tlv = cmsg->tlvs[type]; + uint16_t length = sizeof(struct kni_cmsg_tlv) + size; + if(tlv == NULL) + { + tlv = (struct kni_cmsg_tlv*)ALLOC(char, length); + cmsg->nr_tlvs++; + cmsg->size += length; + } + tlv->type = type; + tlv->length = length; + memcpy(tlv->value_as_string, value, size); + cmsg->tlvs[type] = tlv; + return 0; +} + +int kni_cmsg_get(struct kni_cmsg *cmsg, uint16_t type, uint16_t *size, unsigned char **pvalue) +{ + struct kni_cmsg_tlv *tlv = NULL; + if(type >= KNI_CMSG_TLV_NR_MAX || (tlv = cmsg->tlvs[type]) == NULL) + { + *size = 0; + return KNI_CMSG_INVALID_TYPE; + } + *size = tlv->length - sizeof(struct kni_cmsg_tlv); + *pvalue = tlv->value_as_string; + return 0; +} + +uint16_t kni_cmsg_serialize_size_get(struct kni_cmsg *cmsg) +{ + return cmsg->size; +} + +int kni_cmsg_serialize(struct kni_cmsg *cmsg, unsigned char *buff, uint16_t bufflen, uint16_t *serialize_len) +{ + //size是serialize之后的实际长度 + uint16_t size = cmsg->size; + //传入buff是否够长 + if(bufflen < size) + { + return KNI_CMSG_BUFF_NOT_ENOUGH; + } + //size是否正确 + if(size < sizeof(struct kni_cmsg_serialize_header)) + { + return KNI_CMSG_INVALID_FORMAT; + } + struct kni_cmsg_serialize_header *header = (struct kni_cmsg_serialize_header*)buff; + header->__magic__[0] = 0x4d; + header->__magic__[1] = 0x5a; + header->nr_tlvs = htons(cmsg->nr_tlvs); + uint16_t offset = sizeof(struct kni_cmsg_serialize_header); + //检查nr_tlvs是否合法 + int count = 0; + for(int i = 0; i < KNI_CMSG_TLV_NR_MAX; i++){ + if(cmsg->tlvs[i] != NULL) + { + count++; + } + } + if(count != cmsg->nr_tlvs) + { + return KNI_CMSG_INVALID_FORMAT; + } + //序列化 + for(int i = 0; i < KNI_CMSG_TLV_NR_MAX; i++) + { + struct kni_cmsg_tlv *tlv = cmsg->tlvs[i]; + if(tlv == NULL) + { + continue; + } + if(i != tlv->type) + { + return KNI_CMSG_INVALID_FORMAT; + } + uint16_t length = tlv->length; + if(length < sizeof(struct kni_cmsg_tlv) || offset + length > size) + { + return KNI_CMSG_INVALID_FORMAT; + } + memcpy((char*)header + offset, (void*)tlv, length); + struct kni_cmsg_tlv *tlv1 = (struct kni_cmsg_tlv*)((char*)header + offset); + tlv1->type = htons(tlv->type); + tlv1->length = htons(tlv->length); + offset += length; + } + //检查size是否正确 + if(offset != size) + { + return KNI_CMSG_INVALID_FORMAT; + } + *serialize_len = size; + return 0; +} + +//反序列化 +int kni_cmsg_deserialize(const unsigned char *data, uint16_t len, struct kni_cmsg** pcmsg) +{ + struct kni_cmsg *cmsg = NULL; + struct kni_cmsg_serialize_header *header = (struct kni_cmsg_serialize_header*)data; + int offset = 0, nr_tlvs = -1; + if(len < sizeof(struct kni_cmsg_serialize_header)) + { + goto error_out; + } + if(header->__magic__[0] != 0x4d || header->__magic__[1] != 0x5a) + { + goto error_out; + } + cmsg = ALLOC(struct kni_cmsg, 1); + offset = sizeof(struct kni_cmsg_serialize_header); + nr_tlvs = ntohs(header->nr_tlvs); + for(int i = 0; i < nr_tlvs; i++) + { + struct kni_cmsg_tlv *tlv = (struct kni_cmsg_tlv*)(data + offset); + if(offset + sizeof(struct kni_cmsg_tlv) > len) + { + goto error_out; + } + uint16_t type = ntohs(tlv->type); + uint16_t length = ntohs(tlv->length); + if(length < sizeof(struct kni_cmsg_tlv) || offset + length > len) + { + goto error_out; + } + int ret = kni_cmsg_set(cmsg, type, data + offset + sizeof(struct kni_cmsg_tlv), length - sizeof(struct kni_cmsg_tlv)); + if(ret < 0) + { + goto error_out; + } + offset += length; + } + cmsg->size = offset; + *pcmsg = cmsg; + return 0; + +error_out: + kni_cmsg_destroy(cmsg); + return KNI_CMSG_INVALID_FORMAT; +} diff --git a/common/src/kni_utils.cpp b/common/src/kni_utils.cpp index e3ce0fd..31a1965 100644 --- a/common/src/kni_utils.cpp +++ b/common/src/kni_utils.cpp @@ -1,4 +1,15 @@ #include "kni_utils.h" +#include +#include + +int kni_stream_addr_trans(struct ipaddr* addr, char *output, int len){ + char saddr[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(addr->v4->saddr), saddr, INET_ADDRSTRLEN); + char daddr[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(addr->v4->daddr), daddr, INET_ADDRSTRLEN); + snprintf(output, len, "%s:%d -> %s:%d", saddr, ntohs(addr->v4->source), daddr, ntohs(addr->v4->dest)); + return 0; +} uint16_t kni_ip_checksum(const void *buf, size_t hdr_len){ unsigned long sum = 0; @@ -148,4 +159,97 @@ struct kni_tcpopt_info* kni_get_tcpopt(struct tcphdr* tcphdr,int tcphdr_len){ } } return tcpopt; +} + + +int kni_ipv4_addr_get_by_eth(const char *ifname, uint32_t *ip){ + struct ifreq ifr; + int sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd == -1) { + goto error_out; + } + strcpy(ifr.ifr_name, ifname); + if(ioctl(sockfd, SIOCGIFADDR, &ifr) < 0){ + goto error_out; + } + *ip = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr; + close(sockfd); + return 0; + +error_out: + close(sockfd); + return -1; +} + +static int __wrapper_MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, unsigned value, void *logger, const char *symbol) +{ + int ret = MESA_htable_set_opt(table, opt_type, &value, (int)(sizeof(value))); + if(unlikely(ret != 0)) + { + KNI_LOG_ERROR(logger, "Failed at MESA_htable_set_opt, htable is %s, opt_type is %d", symbol, opt_type); + } + return ret; +} + +static int __wrapper_MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, void * val, size_t len, void *logger, const char *symbol) +{ + int ret = MESA_htable_set_opt(table, opt_type, val, (int)len); + if(unlikely(ret != 0)) + { + KNI_LOG_ERROR(logger, "Failed at MESA_htable_set_opt, htable is %s, opt_type is %d", symbol, opt_type); + } + return ret; +} + +MESA_htable_handle kni_create_htable(const char *profile, const char *section, void *free_data_cb, void *expire_notify_cb, void *logger) +{ + int mho_screen_print_ctrl; + int mho_thread_safe; + int mho_mutex_num; + int mho_hash_slot_size; + int mho_hash_max_element_num; + int mho_expire_time; + char mho_eliminate_type[KNI_SYMBOL_MAX]; + MESA_load_profile_int_def(profile, section, "mho_screen_print_ctrl", &mho_screen_print_ctrl, 1); + MESA_load_profile_int_def(profile, section, "mho_thread_safe", &mho_thread_safe, 0); + MESA_load_profile_int_def(profile, section, "mho_mutex_num", &mho_mutex_num, 12); + MESA_load_profile_int_def(profile, section, "mho_hash_slot_size", &mho_hash_slot_size, 1234); + MESA_load_profile_int_def(profile, section, "mho_hash_max_element_num", &mho_hash_max_element_num, 12345); + MESA_load_profile_int_def(profile, section, "mho_expire_time", &mho_expire_time, 3600); + MESA_load_profile_string_def(profile, section, "mho_eliminate_type", mho_eliminate_type, sizeof(mho_eliminate_type), "FIFO"); + KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n mho_screen_print_ctrl: %d\n mho_thread_safe: %d\n mho_mutex_num: %d\n" + "mho_hash_slot_size: %d\n mho_hash_max_element_num: %d\n mho_expire_time: %d\n mho_eliminate_type: %s\n", section, + mho_screen_print_ctrl, mho_thread_safe, mho_mutex_num, mho_hash_slot_size, mho_hash_max_element_num, mho_expire_time, mho_eliminate_type); + MESA_htable_handle htable = MESA_htable_born(); + if(htable == NULL) + { + KNI_LOG_ERROR(logger, "MESA_htable: failed at MESA_htable_born"); + return NULL; + } + __wrapper_MESA_htable_set_opt(htable, MHO_SCREEN_PRINT_CTRL, mho_screen_print_ctrl, logger, section); + __wrapper_MESA_htable_set_opt(htable, MHO_THREAD_SAFE, mho_thread_safe, logger, section); + __wrapper_MESA_htable_set_opt(htable, MHO_MUTEX_NUM, mho_mutex_num, logger, section); + __wrapper_MESA_htable_set_opt(htable, MHO_HASH_SLOT_SIZE, mho_hash_slot_size, logger, section); + __wrapper_MESA_htable_set_opt(htable, MHO_HASH_MAX_ELEMENT_NUM, mho_hash_max_element_num, logger, section); + __wrapper_MESA_htable_set_opt(htable, MHO_EXPIRE_TIME, mho_expire_time, logger, section); + if(strncmp(mho_eliminate_type, "LRU", KNI_SYMBOL_MAX) == 0) + { + __wrapper_MESA_htable_set_opt(htable, MHO_ELIMIMINATE_TYPE, HASH_ELIMINATE_ALGO_LRU, logger, section); + } + else + { + __wrapper_MESA_htable_set_opt(htable, MHO_ELIMIMINATE_TYPE, HASH_ELIMINATE_ALGO_FIFO, logger, section); + } + + __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_FREE, + (void *)free_data_cb, sizeof(free_data_cb), logger, section); + //ret = __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_EXPIRE_NOTIFY, + // (void *)key_keeper_verify_cb); + int ret = MESA_htable_mature(htable); + if(unlikely(ret != 0)) + { + KNI_LOG_ERROR(logger, "MESA_htable: failed at MESA_htable_mature, htable is %s", section); + return NULL; + } + return htable; } \ No newline at end of file diff --git a/common/test/test_cmsg.cpp b/common/test/test_cmsg.cpp new file mode 100644 index 0000000..0b2104b --- /dev/null +++ b/common/test/test_cmsg.cpp @@ -0,0 +1,49 @@ + + +#include "kni_utils.h" +#include "kni_cmsg.h" + +int main(){ + //init + struct kni_cmsg *cmsg = kni_cmsg_init(); + + //set + uint32_t value = 0x12345678; + int ret = kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_SEQ, (const unsigned char*)(&value), 4); + printf("kni_cmsg_set: ret is %d\n", ret); + + //get TCP_RESTORE_INFO_TLV_SEQ + uint16_t size = -1; + unsigned char *value1 = NULL; + ret = kni_cmsg_get(cmsg, TFE_CMSG_TCP_RESTORE_SEQ, &size, &value1); + printf("kni_cmsg_get: ret is %d, type is TCP_RESTORE_INFO_TLV_SEQ, value is 0x%02x, value_size is %d\n", ret, ((uint32_t*)value1)[0], size); + + //get_serialize_size + size = kni_cmsg_serialize_size_get(cmsg); + printf("kni_cmsg_serialize_size_get: size is %d\n", size); + + //serialize + unsigned char buff[size]; + uint16_t serialize_len = -1; + ret = kni_cmsg_serialize(cmsg, buff, size, &serialize_len); + printf("kni_cmsg_serialize: ret is %d, serialize_len is %d, serialize result is: ", ret, serialize_len); + for(int i = 0; i < serialize_len; i++){ + printf("%02x ", buff[i]); + } + printf("\n"); + kni_cmsg_destroy(cmsg); + printf("kni_cmsg_destroy cmsg\n"); + + //deserialize + struct kni_cmsg *cmsg1 = NULL; + ret = kni_cmsg_deserialize(buff, serialize_len, &cmsg1); + printf("kni_cmsg_deserialize: ret is %d\n", ret); + + //get TCP_RESTORE_INFO_TLV_SEQ + size = -1; + unsigned char *value2 = NULL; + ret = kni_cmsg_get(cmsg1, TFE_CMSG_TCP_RESTORE_SEQ, &size, &value2); + printf("kni_cmsg_get: ret is %d, type is TCP_RESTORE_INFO_TLV_SEQ, value is 0x%02x, value_size is %d\n", ret, ((uint32_t*)value2)[0], size); + kni_cmsg_destroy(cmsg1); + printf("kni_cmsg_destroy cmsg1\n"); +} diff --git a/common/test/test_uuid.cpp b/common/test/test_uuid.cpp new file mode 100644 index 0000000..b4bb12d --- /dev/null +++ b/common/test/test_uuid.cpp @@ -0,0 +1,12 @@ +#include +#include "uuid/uuid.h" + +int main(){ + for(int i = 0; i < 10; i++){ + uuid_t uu; + char buf[37]; + uuid_generate_random(uu); + uuid_unparse(uu, buf); + printf("uuid is: %s\n", buf); + } +} \ No newline at end of file diff --git a/conf/kni.conf b/conf/kni.conf index b159024..f4b54fe 100644 --- a/conf/kni.conf +++ b/conf/kni.conf @@ -1,20 +1,50 @@ [global] log_path = ./log/kni/kni.log log_level = 10 +tfe_count = 1 +local_eth = enp8s0 [maat] -readconf_mode = 1 +readconf_mode = 2 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 tablename_intercept_ip = PXY_INTERCEPT_IP tablename_intercept_domain = PXY_INTERCEPT_DOMAIN compile_alias = COMPILE_ALIAS [marsio] appsym = knifw -dev_eth_symbol = eth4 dev_vxlan_symbol = vxlan_user +src_mac_addr = 00:0e:c6:d6:72:c1 + +[tfe0] +mac_addr = fe:65:b7:03:50:bd +dev_eth_symbol = ens1f5 + +[tfe1] +mac_addr = fe:65:b7:03:50:bd +dev_eth_symbol = eth8 + +[tfe2] +mac_addr = fe:65:b7:03:50:bd +dev_eth_symbol = eth9 [field_stat] stat_path = ./fs2_kni.status +[send_logger] +switch = 1 +kafka_topic = SESSION-RECORD-LOG +kafka_brokerlist = 192.168.10.121:9092,192.168.10.122:9092,192.168.10.123:9092 + +[kafka] +queue.buffering.max.messages = 1000000 +topic.metadata.refresh.interval.ms = 600000 +security.protocol = MG + +[tfe_cmsg_receiver] +listen_eth = enp8s0 +listen_port = 8888 \ No newline at end of file diff --git a/conf/sapp/conflist_business.inf b/conf/sapp/conflist_business.inf index d2df915..b7f6d47 100644 --- a/conf/sapp/conflist_business.inf +++ b/conf/sapp/conflist_business.inf @@ -1 +1 @@ -./plug/business/kni/kni.inf \ No newline at end of file +./plug/business/kni/kni.inf diff --git a/conf/sapp/kni/kni.inf b/conf/sapp/kni/kni.inf index bbbc20d..1b0b72e 100644 --- a/conf/sapp/kni/kni.inf +++ b/conf/sapp/kni/kni.inf @@ -1,13 +1,13 @@ [PLUGINFO] PLUGNAME = KNI -SO_PATH = ./plug/business/kni/libkni.so -INIT_FUNC = kni_init -DESTROY_FUNC = +SO_PATH = ./plug/business/kni/kni2.so +INIT_FUNC = kni_init +DESTROY_FUNC = kni_destroy [TCP_ALL] -FUNC_FLAG = all -FUNC_NAME = kni_tcpall_entry +FUNC_FLAG = all +FUNC_NAME = kni_tcpall_entry [HTTP] -FUNC_FLAG = HTTP_HOST -FUNC_NAME = kni_http_entry +FUNC_FLAG = HTTP_HOST +FUNC_NAME = kni_http_entry \ No newline at end of file diff --git a/entry/CMakeLists.txt b/entry/CMakeLists.txt index 5db1562..76a7494 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) +add_library(kni SHARED src/kni_entry.cpp src/kni_maat.cpp src/kni_send_logger.cpp) target_include_directories(kni PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) -target_link_libraries(kni common MESA_prof_load MESA_field_stat maatframe marsio) \ No newline at end of file +target_link_libraries(kni common MESA_prof_load MESA_htable MESA_field_stat maatframe marsio uuid cjson rdkafka) \ No newline at end of file diff --git a/entry/include/kni_entry.h b/entry/include/kni_entry.h deleted file mode 100644 index 25f16c0..0000000 --- a/entry/include/kni_entry.h +++ /dev/null @@ -1,108 +0,0 @@ - -#define HTTP_PROJECT_NAME "kni_http_tag" -#define BURST_MAX 1 - -enum kni_protocol{ - KNI_PROTOCOL_UNKNOWN = 0, - KNI_PROTOCOL_SSL, - KNI_PROTOCOL_HTTP, -}; - -struct http_project{ - int host_len; - char host[KNI_DOMAIN_MAX]; -}; - -struct pme_info{ - int protocol; - int action; - struct kni_tcpopt_info *client_tcpopt; - struct kni_tcpopt_info *server_tcpopt; -}; - -struct wrapped_packet{ - char data[KNI_MTU]; -}; - -struct tcp_option_restore{ - uint8_t kind; - uint8_t len; - uint16_t offset; -}; - -struct kni_marsio_handle{ - struct mr_instance *instance; - struct mr_vdev *dev_eth_handler; - struct mr_vdev *dev_vxlan_handler; - struct mr_sendpath *dev_eth_sendpath; - struct mr_sendpath *dev_vxlan_sendpath; -}; - -struct protocol_identify_result{ - int protocol; - char domain[KNI_DOMAIN_MAX]; - int domain_len; -}; - - -struct tfe_receiver_args{ - void *logger; - struct kni_marsio_handle *marsio_handle; -}; - -//TODO: 有些字段可以不要 -struct pkt_info{ - struct iphdr *iphdr; - int iphdr_len; - int ip_totlen; - struct tcphdr *tcphdr; - int tcphdr_len; - char *data; - int data_len; -}; - -enum tcp_restore_info_tlv_type -{ - TCP_RESTORE_INFO_TLV_SEQ, - TCP_RESTORE_INFO_TLV_ACK, - TCP_RESTORE_INFO_TLV_MSS_CLIENT, - TCP_RESTORE_INFO_TLV_MSS_SERVER, - TCP_RESTORE_INFO_TLV_WSACLE_CLIENT, - TCP_RESTORE_INFO_TLV_WSACLE_SERVER, - TCP_RESTORE_INFO_TLV_SACK_CLIENT, - TCP_RESTORE_INFO_TLV_SACK_SERVER, - TCP_RESTORE_INFO_TLV_TS_CLIENT, - TCP_RESTORE_INFO_TLV_TS_SERVER, - TCP_RESTORE_INFO_TLV_PROTOCOL, - TCP_RESTORE_INFO_TLV_USER_DEFINED -}; - -struct tcp_restore_info_tlv -{ - uint16_t type; - uint16_t length; - - union - { - uint8_t value_as_uint8[0]; - uint16_t value_as_uint16[0]; - uint32_t value_as_uint32[0]; - unsigned char value_as_string[0]; - }; -} __attribute__((packed)); - -struct tcp_restore_info_header -{ - uint8_t __magic__[2]; /* Must be 0x4d, 0x5a */ - uint16_t nr_tlvs; - struct tcp_restore_info_tlv tlvs[0]; -} __attribute__((packed)); - -struct kni_handle{ - int http_project_id; - struct kni_marsio_handle *marsio_handle; - struct kni_maat_handle *maat_handle; - void *logger; -}; - -#define TCP_RESTORE_HEADER_MAX 128 \ No newline at end of file diff --git a/entry/include/kni_maat.h b/entry/include/kni_maat.h index 66455de..2ad819b 100644 --- a/entry/include/kni_maat.h +++ b/entry/include/kni_maat.h @@ -3,19 +3,15 @@ #define KNI_MAAT_READCONF_JSON 1 #define KNI_MAAT_READCONF_REDIS 2 #define KNI_MAAT_RULE_NUM_MAX 8 -struct kni_maat_handle{ - Maat_feather_t feather; - int tableid_intercept_ip; - int tableid_intercept_domain; - void *logger; -}; +struct kni_maat_handle; enum kni_action{ KNI_ACTION_UNKNOWN = 0, KNI_ACTION_INTERCEPT, KNI_ACTION_BYPASS, }; + struct kni_maat_handle* kni_maat_init(const char* profile, void *logger); void kni_maat_destroy(struct kni_maat_handle *handle); -int kni_maat_scan_ip(struct kni_maat_handle* handle, struct ipaddr *addr, int thread_seq); -int kni_maat_scan_domain(struct kni_maat_handle* handle, char *domain, int domain_len, int thread_seq); \ No newline at end of file +int kni_maat_scan_ip(struct kni_maat_handle* handle, struct ipaddr *addr, int thread_seq, int *policy_id); +int kni_maat_scan_domain(struct kni_maat_handle* handle, char *domain, int domain_len, int thread_seq, int *policy_id); \ No newline at end of file diff --git a/entry/include/kni_send_logger.h b/entry/include/kni_send_logger.h new file mode 100644 index 0000000..f5750ad --- /dev/null +++ b/entry/include/kni_send_logger.h @@ -0,0 +1,5 @@ + +struct kni_send_logger; +struct kni_send_logger* kni_send_logger_init(const char *profile, void *logger); +void kni_send_logger_destroy(struct kni_send_logger *handle); +int kni_send_logger_sendlog(kni_send_logger *handle, char *log_msg, int log_msg_len); \ No newline at end of file diff --git a/entry/src/kni_entry.cpp b/entry/src/kni_entry.cpp index 34f843a..ee53b4f 100644 --- a/entry/src/kni_entry.cpp +++ b/entry/src/kni_entry.cpp @@ -1,9 +1,12 @@ #include "kni_utils.h" #include "ssl_utils.h" -#include "kni_entry.h" #include "marsio.h" #include "kni_maat.h" #include "MESA/http.h" +#include "kni_cmsg.h" +#include "uuid/uuid.h" +#include "cjson/cJSON.h" +#include "kni_send_logger.h" extern int g_iThreadNum; @@ -12,15 +15,31 @@ extern int g_iThreadNum; //PROT_STATE_GIVEME/DROPME: 当前http会话的剩下包是否回调 -//TODO: seq, ack 是当拿到client hello时传给秋秋,取client hello的 seq, ack, 时间戳和sack没有解, 不用解,只需要知道enable/disable即可 +//seq, ack 是当拿到client hello时传给秋秋,取client hello的 seq, ack, 时间戳和sack没有解, 不用解,只需要知道enable/disable即可 //TODO: 注意内存泄漏,ALLOC对应的FREE, 还有calloc -//TOOD: 函数加static -//TODO: 统计syn/syn/ack个数,流个数, pending not syn个数, not syn/ack个数, 单向流数量, 发往tfe的包数,流数,收到的包数,流数 +//函数加static +//统计syn/syn/ack个数,流个数, pending not syn个数, not syn/ack个数, 单向流数量, 发往tfe的包数,流数,收到的包数,流数 done //多个tcpall插件,APP_STATE_DROPPKT, APP_STATE_FAWPKT? 有一个droppkt,就不给后面的插件了 //一个tcp流中有多个http,ssl会话的情况,只扫描第一个 +//TODO: 统计增加多个tfe实例 +//TODO: kafka写日志 +//TODO: taobao穿了?? +//TODO: 捕的包里面第一个client hello是没有控制信息的 +//TODO: bypass之后继续统计,不要dropme, dropme之后会立即调用close +//TODO: - +/* + 1. 对pme来说,只有sapp和tfe都release之后才会释放内存 + 1.1. sapp有自己的超时淘汰,所以肯定会release + 1.2. 当收到tfe的cmsg信息时, set tfe_release = 1 + 1.3 从收到sapp的release信息之后开始计时(查一下hash表),超时之后 set tfe_release = 1 + 2. 对traceid2pme的hash表来说 + 2.1 收到tfe的cmsg信息之后需要查询,查完就可以删掉了 + 2.2 hash表的超时淘汰函数: + sapp_release = 0表示计时未开始,不能删除 + sapp_release = 1表示已经收到sapp的release信息, 确定超时 +*/ struct kni_handle *g_kni_handle = NULL; struct kni_field_stat_handle *g_kni_fs_handle = NULL; @@ -28,13 +47,260 @@ struct kni_field_stat_handle *g_kni_fs_handle = NULL; //struct kni_marsio_handle *g_kni_marsio_handle; //g_iThreadNum 为sapp线程数 -static struct pme_info* pme_info_new(){ +#define HTTP_PROJECT_NAME "kni_http_tag" +#define BURST_MAX 1 +#define STREAM_TRACE_ID_LEN 37 +#define TFE_COUNT_MAX 16 + +enum kni_protocol{ + KNI_PROTOCOL_UNKNOWN = 0, + KNI_PROTOCOL_SSL, + KNI_PROTOCOL_HTTP, +}; + +struct http_project{ + int host_len; + char host[KNI_DOMAIN_MAX]; +}; + +struct pme_info{ + int protocol; + int policy_id; + int action; + int service; + struct kni_tcpopt_info *client_tcpopt; + struct kni_tcpopt_info *server_tcpopt; + int tfe_id; + void *logger; + char stream_trace_id[STREAM_TRACE_ID_LEN]; + char host[KNI_DOMAIN_MAX]; //http only + char sni[KNI_DOMAIN_MAX]; //ssl only + //tfe_release = 1: tfe don't need pmeinfo + int tfe_release; + int sapp_release; + //kafka log + struct streaminfo *stream; + time_t start_time; + uint64_t con_duration; + //from tfe, kafka log + int intercept_state; + int pinningst; //默认为0, 表示没有从tfe收到 + uint64_t ssl_server_side_latency; + uint64_t ssl_client_side_latency; + char ssl_server_side_version[KNI_SYMBOL_MAX]; + char ssl_client_side_version[KNI_SYMBOL_MAX]; + int ssl_cert_verify; + char ssl_error[KNI_STRING_MAX]; +}; + +struct wrapped_packet{ + char data[KNI_MTU]; +}; + +struct tcp_option_restore{ + uint8_t kind; + uint8_t len; + uint16_t offset; +}; + +struct tfe_instance{ + struct mr_vdev *dev_eth_handler; + struct mr_sendpath *dev_eth_sendpath; + char mac_addr[6]; +}; + +struct kni_marsio_handle{ + struct mr_instance *instance; + struct tfe_instance *tfe_instance_list[TFE_COUNT_MAX]; + struct mr_vdev *dev_vxlan_handler; + struct mr_sendpath *dev_vxlan_sendpath; + char src_mac_addr[6]; +}; + +struct protocol_identify_result{ + int protocol; + char domain[KNI_DOMAIN_MAX]; + int domain_len; +}; + + +struct thread_tfe_data_receiver_args{ + void *logger; + struct kni_marsio_handle *marsio_handle; + int tfe_id; +}; + +struct thread_tfe_cmsg_receiver_args{ + void *logger; + char profile[KNI_SYMBOL_MAX]; +}; + +//TODO: 有些字段可以不要 +struct pkt_info{ + struct iphdr *iphdr; + int iphdr_len; + int ip_totlen; + struct tcphdr *tcphdr; + int tcphdr_len; + char *data; + int data_len; +}; + +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; + int tfe_count; + uint32_t local_ipv4; + void *local_logger; +}; + +struct traceid2pme_search_cb_args{ + struct kni_cmsg *cmsg; + void *logger; +}; + +static struct pme_info* pme_info_new(const struct streaminfo *stream, int thread_seq, void *logger){ struct pme_info* pmeinfo = ALLOC(struct pme_info, 1); + pmeinfo->tfe_id = g_kni_handle->tfe_count > 0 ? thread_seq % g_kni_handle->tfe_count : -1; + uuid_t uu; + uuid_generate_random(uu); + uuid_unparse(uu, pmeinfo->stream_trace_id); + pmeinfo->stream = (struct streaminfo*)stream; + pmeinfo->start_time = time(NULL); + pmeinfo->logger = logger; return pmeinfo; } +static int sendlog_to_kafka(struct pme_info *pmeinfo, void *local_logger){ + //创建cjson对象 + cJSON *log_obj = cJSON_CreateObject(); + //stream_trace_id + cJSON_AddStringToObject(log_obj, "stream_trace_id", pmeinfo->stream_trace_id); + //policy_id + cJSON_AddNumberToObject(log_obj, "policy_id", pmeinfo->policy_id); + //action + cJSON_AddNumberToObject(log_obj, "action", pmeinfo->action); + //service + cJSON_AddNumberToObject(log_obj, "service", pmeinfo->service); + //start_time + cJSON_AddNumberToObject(log_obj, "start_time", pmeinfo->start_time); + //end_time + cJSON_AddNumberToObject(log_obj, "end_time", time(NULL)); + //stream_info: addr_type, trans_proto, client_ip, client_port, server_ip, server_port + const struct layer_addr *addr = &(pmeinfo->stream->addr); + char client_ip_str[INET6_ADDRSTRLEN] = ""; + char server_ip_str[INET6_ADDRSTRLEN] = ""; + switch(addr->addrtype){ + case ADDR_TYPE_IPV4: + cJSON_AddNumberToObject(log_obj, "addr_type", 4); + inet_ntop(AF_INET, &addr->tuple4_v4->saddr, client_ip_str, sizeof(client_ip_str)); + inet_ntop(AF_INET, &addr->tuple4_v4->daddr, server_ip_str, sizeof(server_ip_str)); + cJSON_AddStringToObject(log_obj, "client_ip", client_ip_str); + cJSON_AddStringToObject(log_obj, "server_ip", server_ip_str); + cJSON_AddNumberToObject(log_obj, "client_port", ntohs(addr->tuple4_v4->source)); + cJSON_AddNumberToObject(log_obj, "server_port", ntohs(addr->tuple4_v4->dest)); + cJSON_AddStringToObject(log_obj, "trans_proto", "IPv4_TCP"); + break; + case ADDR_TYPE_IPV6: + cJSON_AddNumberToObject(log_obj, "addr_type", 6); + inet_ntop(AF_INET6, &addr->tuple4_v6->saddr, client_ip_str, sizeof(client_ip_str)); + inet_ntop(AF_INET6, &addr->tuple4_v6->daddr, server_ip_str, sizeof(server_ip_str)); + cJSON_AddStringToObject(log_obj, "client_ip", client_ip_str); + cJSON_AddStringToObject(log_obj, "server_ip", server_ip_str); + cJSON_AddNumberToObject(log_obj, "client_port", ntohs(addr->tuple4_v6->source)); + cJSON_AddNumberToObject(log_obj, "server_port", ntohs(addr->tuple4_v6->dest)); + cJSON_AddStringToObject(log_obj, "trans_proto", "IPv6_TCP"); + break; + default: + break; + } + //entrance_id: 0 + cJSON_AddNumberToObject(log_obj, "entrance_id", 0); + //device_id: 0 + cJSON_AddNumberToObject(log_obj, "device_id", 0); + //link_id: 0 + cJSON_AddNumberToObject(log_obj, "link_id", 0); + //isp: null + cJSON_AddStringToObject(log_obj, "isp", ""); + //encap_type: from sapp, 先填0 + cJSON_AddNumberToObject(log_obj, "encap_type", 0); + + //pinning state: from tfe + cJSON_AddNumberToObject(log_obj, "pinningst", pmeinfo->pinningst); + //intercept state: from tfe + cJSON_AddNumberToObject(log_obj, "intercept_state", pmeinfo->intercept_state); + //ssl upstream latency: from tfe + cJSON_AddNumberToObject(log_obj, "ssl_server_side_latency", pmeinfo->ssl_server_side_latency); + //ssl downstream latency: from tfe + cJSON_AddNumberToObject(log_obj, "ssl_client_side_latency", pmeinfo->ssl_client_side_latency); + //ssl upstream version: from tfe + cJSON_AddStringToObject(log_obj, "ssl_server_side_version", pmeinfo->ssl_server_side_version); + //ssl downstream version: from tfe + cJSON_AddStringToObject(log_obj, "ssl_client_side_version", pmeinfo->ssl_client_side_version); + //ssl cert verify + cJSON_AddNumberToObject(log_obj, "ssl_cert_verify", pmeinfo->ssl_cert_verify); + + //direction: 0 + cJSON_AddNumberToObject(log_obj, "direction", 0); + //stream_dir: from sapp + cJSON_AddNumberToObject(log_obj, "stream_dir", pmeinfo->stream->dir); + //cap_ip: 从网卡名得到 + char local_ipv4_str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, &(g_kni_handle->local_ipv4), local_ipv4_str, sizeof(local_ipv4_str)); + cJSON_AddStringToObject(log_obj, "cap_ip", local_ipv4_str); + //addr_list + cJSON_AddStringToObject(log_obj, "addr_list", ""); + //host: http_only + cJSON_AddStringToObject(log_obj, "host", pmeinfo->host); + //sni: ssl only + cJSON_AddStringToObject(log_obj, "sni", pmeinfo->sni); + //c2s_pkt_num + cJSON_AddNumberToObject(log_obj, "c2s_pkt_num", pmeinfo->stream->ptcpdetail->serverpktnum); + //s2c_pkt_num + cJSON_AddNumberToObject(log_obj, "s2c_pkt_num", pmeinfo->stream->ptcpdetail->clientpktnum); + //c2s_byte_num + cJSON_AddNumberToObject(log_obj, "c2s_byte_num", pmeinfo->stream->ptcpdetail->serverbytes); + //s2c_byte_num + cJSON_AddNumberToObject(log_obj, "s2c_byte_num", pmeinfo->stream->ptcpdetail->clientbytes); + int ret = -1; + char *log_msg = cJSON_Print(log_obj); + cJSON_Delete(log_obj); + if(log_msg == NULL){ + KNI_LOG_ERROR(local_logger, "Failed at cJSON_Print"); + goto error_out; + } + KNI_LOG_DEBUG(local_logger, "log_msg is %s\n", log_msg); + ret = kni_send_logger_sendlog(g_kni_handle->send_logger, log_msg, strlen(log_msg)); + if(ret < 0){ + KNI_LOG_ERROR(local_logger, "Failed at kni_send_logger_sendlog, ret is %d", ret); + goto error_out; + //重试逻辑? + } + FREE(&log_msg); + return 0; + +error_out: + if(log_msg != NULL){ + FREE(&log_msg); + } + return -1; +} + static void pme_info_destroy(struct pme_info *pmeinfo){ - if(pmeinfo != NULL){ + void *logger = pmeinfo->logger; + if(pmeinfo != NULL && pmeinfo->sapp_release == 1 && pmeinfo->tfe_release == 1){ + int ret = sendlog_to_kafka(pmeinfo, logger); + if(ret < 0){ + KNI_LOG_ERROR(logger, "Failed at sendlog to kafka"); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDLOG_FAIL], 0, FS_OP_ADD, 1); + } + else{ + KNI_LOG_INFO(logger, "Succeed sendlog to kafka"); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDLOG_SUCC], 0, FS_OP_ADD, 1); + } if(pmeinfo->client_tcpopt != NULL){ FREE(&(pmeinfo->client_tcpopt)); } @@ -76,52 +342,87 @@ static int protocol_identify(const struct streaminfo* stream, char *buf, int len result->protocol = KNI_PROTOCOL_UNKNOWN; return 0; } - -static int tcp_restore_info_tlv_add(uint16_t type, uint16_t value_len, uint32_t value, char *header, int *offset, int *nr_tlvs){ - int tlv_len = sizeof(tcp_restore_info_tlv) + value_len; - struct tcp_restore_info_tlv *tlv_info = (struct tcp_restore_info_tlv*)calloc(tlv_len, 1); - tlv_info->type= htons(type); - tlv_info->length = htons(tlv_len); - if(value_len == 1){ - tlv_info->value_as_uint8[0] = value; +static int wrapped_kni_cmsg_set(struct kni_cmsg *cmsg, uint16_t type, const unsigned char *value, uint16_t size){ + 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", type); } - if(value_len == 2){ - tlv_info->value_as_uint16[0] = value; - } - if(value_len == 4){ - tlv_info->value_as_uint32[0] = value; - } - memcpy(header + *offset, tlv_info, tlv_len); - *offset += tlv_len; - (*nr_tlvs)++; - free(tlv_info); - return 0; + return ret; } -static struct tcp_restore_info_header* tcp_restore_info_header_new(struct pme_info *pmeinfo, struct pkt_info *pktinfo, int *len){ - struct tcp_restore_info_header *header = (struct tcp_restore_info_header*)calloc(TCP_RESTORE_HEADER_MAX, 1); - int offset = sizeof(struct tcp_restore_info_header); - int nr_tlvs = 0; - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_SEQ, 4, pktinfo->tcphdr->seq, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_ACK, 4, pktinfo->tcphdr->ack_seq, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_MSS_CLIENT, 2, htons(pmeinfo->client_tcpopt->mss), (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_MSS_SERVER, 2, htons(pmeinfo->server_tcpopt->mss), (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_WSACLE_CLIENT, 1, pmeinfo->client_tcpopt->wscale, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_WSACLE_SERVER, 1, pmeinfo->server_tcpopt->wscale, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_SACK_CLIENT, 1, pmeinfo->client_tcpopt->sack, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_SACK_SERVER, 1, pmeinfo->server_tcpopt->sack, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_TS_CLIENT, 1, pmeinfo->client_tcpopt->ts, (char*)header, &offset, &nr_tlvs); - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_TS_SERVER, 1, pmeinfo->server_tcpopt->ts, (char*)header, &offset, &nr_tlvs); +static unsigned char* kni_cmsg_serialize_header_new(struct pme_info *pmeinfo, struct pkt_info *pktinfo, uint16_t *len){ + void *logger = g_kni_handle->local_logger; + uint16_t bufflen = 0, serialize_len = 0; + unsigned char *buff = NULL; uint8_t protocol_type = pmeinfo->protocol == KNI_PROTOCOL_SSL ? 0x1 : 0x0; - tcp_restore_info_tlv_add(TCP_RESTORE_INFO_TLV_PROTOCOL, 1, protocol_type, (char*)header, &offset, &nr_tlvs); - header->__magic__[0] = 0x4d; - header->__magic__[1] = 0x5a; - header->nr_tlvs = htons(nr_tlvs); - *len = offset; - return header; + struct kni_cmsg *cmsg = kni_cmsg_init(); + int policy_id = -1; + char *trace_id = NULL; + uint32_t seq = pktinfo->tcphdr->seq; + uint32_t ack = pktinfo->tcphdr->ack_seq; + uint16_t client_mss = htons(pmeinfo->client_tcpopt->mss); + uint16_t server_mss = htons(pmeinfo->server_tcpopt->mss); + //seq + int ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_SEQ, (const unsigned char*)&seq, 4); + if(ret < 0) goto error_out; + //ack + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_ACK, (const unsigned char*)&ack, 4); + if(ret < 0) goto error_out; + //client mss + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_MSS_CLIENT, (const unsigned char*)&client_mss, 2); + if(ret < 0) goto error_out; + //server mss + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_MSS_SERVER, (const unsigned char*)&server_mss, 2); + if(ret < 0) goto error_out; + //client wscale + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, (const unsigned char*)&(pmeinfo->client_tcpopt->wscale), 1); + if(ret < 0) goto error_out; + //server wscale + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_SERVER, (const unsigned char*)&(pmeinfo->server_tcpopt->wscale), 1); + if(ret < 0) goto error_out; + //client sack + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_SACK_CLIENT, (const unsigned char*)&(pmeinfo->client_tcpopt->sack), 1); + if(ret < 0) goto error_out; + //server sack + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_SACK_SERVER, (const unsigned char*)&(pmeinfo->server_tcpopt->sack), 1); + 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); + 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); + if(ret < 0) goto error_out; + //protocol + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (const unsigned char*)&protocol_type, 1); + if(ret < 0) goto error_out; + //maat policy id + policy_id = pmeinfo->policy_id; + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_POLICY_ID, (const unsigned char*)&policy_id, sizeof(policy_id)); + if(ret < 0) goto error_out; + //stream trace id + trace_id = pmeinfo->stream_trace_id; + ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_STREAM_TRACE_ID, (const unsigned char*)trace_id, STREAM_TRACE_ID_LEN); + if(ret < 0) goto error_out; + + bufflen = kni_cmsg_serialize_size_get(cmsg); + buff = (unsigned char*)ALLOC(char, bufflen); + 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", ret); + goto error_out; + } + *len = serialize_len; + kni_cmsg_destroy(cmsg); + return buff; + +error_out: + kni_cmsg_destroy(cmsg); + return NULL; } -static char* tcp_restore_info_header_add(struct pme_info *pmeinfo, struct pkt_info *pktinfo, int *len){ +static char* add_cmsg_to_packet(struct pme_info *pmeinfo, struct pkt_info *pktinfo, int *len){ //tcp option: kind 88, len 4, control_info_len char *new_pkt = (char*)ALLOC(struct wrapped_packet, 1); struct iphdr *iphdr = (struct iphdr*)new_pkt; @@ -145,12 +446,12 @@ static char* tcp_restore_info_header_add(struct pme_info *pmeinfo, struct pkt_in //data memcpy(new_pkt + offset, (void*)pktinfo->data, pktinfo->data_len); offset += pktinfo->data_len; - //tcp_restore_info_header - int header_len = 0; - struct tcp_restore_info_header* header = tcp_restore_info_header_new(pmeinfo, pktinfo, &header_len); + //kni_cmsg_serialize_header + uint16_t header_len = 0; + unsigned char* header = kni_cmsg_serialize_header_new(pmeinfo, pktinfo, &header_len); memcpy(new_pkt + offset, (void*)header, header_len); offset += header_len; - free(header); + FREE(&header); //iphdr: tot_len iphdr->tot_len = htons(offset); //iphdr: checksum @@ -164,33 +465,42 @@ static char* tcp_restore_info_header_add(struct pme_info *pmeinfo, struct pkt_in return new_pkt; } -static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, int raw_len, int thread_seq){ - void *logger = g_kni_handle->logger; - KNI_LOG_DEBUG(logger, "send packet to tfe"); +static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, int raw_len, int thread_seq, int tfe_id){ + void *logger = g_kni_handle->local_logger; + KNI_LOG_DEBUG(logger, "send packet to tfe%d", tfe_id); marsio_buff_t *tx_buffs[BURST_MAX]; unsigned int ret = 1; //TODO: marsio配置文件: 2500 //thread_seq实际上是网卡队列,一个线程对应一个网卡队列, 并不是线程号和网卡队列号一一对应,假设线程号是tid,网卡队列为n,那么tid % n就是网卡队列号 - int alloc_ret = marsio_buff_malloc_device(handle->dev_eth_handler, tx_buffs, ret, 0, thread_seq); + struct mr_vdev *dev_eth_handler = handle->tfe_instance_list[tfe_id]->dev_eth_handler; + struct mr_sendpath *dev_eth_sendpath = handle->tfe_instance_list[tfe_id]->dev_eth_sendpath; + char *src_mac = handle->src_mac_addr; + char *dst_mac = handle->tfe_instance_list[tfe_id]->mac_addr; + int alloc_ret = marsio_buff_malloc_device(dev_eth_handler, tx_buffs, ret, 0, thread_seq); if (alloc_ret < 0){ KNI_LOG_ERROR(logger, "Failed at alloc marsio buffer, ret is %d, thread_seq is %d", ret, thread_seq); return -1; } - void * dst_data = marsio_buff_append(tx_buffs[0], raw_len + 14); - unsigned char ethernet_header[14] = {0xfe, 0x65, 0xb7, 0x03, 0x50, 0xbd, 0xe8, 0x61, 0x1f, 0x13, 0x70, 0x7a, 0x08, 0x00}; - memcpy(dst_data, ethernet_header, 14); + char* dst_data = marsio_buff_append(tx_buffs[0], raw_len + 14); + //ethernet_header[14] + memcpy(dst_data, dst_mac, 6); + memcpy(dst_data + 6, src_mac, 6); + dst_data[12] = 0x08; + dst_data[13] = 0x00; memcpy((char*)dst_data + 14, raw_data, raw_len); - marsio_send_burst(handle->dev_eth_sendpath, thread_seq, tx_buffs, ret); + marsio_send_burst(dev_eth_sendpath, thread_seq, tx_buffs, ret); return 0; } static char pending_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo){ - void *logger = g_kni_handle->logger; + void *logger = g_kni_handle->local_logger; if(!pktinfo->tcphdr->syn){ - //TODO: pending_opstate 不是syn, bypass这个流 + //pending_opstate 不是syn, bypass这个流 KNI_LOG_ERROR(logger, "pending opstate: not syn"); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SYN_EXP], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); + //异常情况,不需要等tfe release, 直接释放 + pmeinfo->tfe_release = 1; return APP_STATE_FAWPKT | APP_STATE_DROPME; } pmeinfo->client_tcpopt = kni_get_tcpopt(pktinfo->tcphdr, pktinfo->tcphdr_len); @@ -198,29 +508,32 @@ static char pending_opstate(const struct streaminfo *stream, struct pme_info *pm return APP_STATE_FAWPKT | APP_STATE_GIVEME; } -static int get_action(struct ipaddr *addr, char *domain, int domain_len, int thread_seq){ +static int get_action(struct ipaddr *addr, char *domain, int domain_len, int thread_seq, int *policy_id){ //return KNI_ACTION_INTERCEPT; - int action = kni_maat_scan_ip(g_kni_handle->maat_handle, addr, thread_seq); + int action = kni_maat_scan_ip(g_kni_handle->maat_handle, addr, thread_seq, policy_id); if(action == KNI_ACTION_BYPASS){ return action; } if(domain_len != 0){ - action = kni_maat_scan_domain(g_kni_handle->maat_handle, domain, domain_len, thread_seq); + action = kni_maat_scan_domain(g_kni_handle->maat_handle, domain, domain_len, thread_seq, policy_id); } return action; } //TODO: 这一块逻辑需要和洋姐和秋秋讨论一下 static char data_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, int thread_seq){ - void *logger = g_kni_handle->logger; + void *logger = g_kni_handle->local_logger; char *buf = (char*)pktinfo->iphdr; int len = pktinfo->ip_totlen; - //action取值只能为 KNI_ACTION_INTERCEPT, KNI_ACTION_UNKNOWN, 因为判断是KNI_ACTION_BYPASS之后直接返回 APP_STATE_DROPME了 if(pmeinfo->action == KNI_ACTION_INTERCEPT){ - send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq); + send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1); return APP_STATE_DROPPKT | APP_STATE_GIVEME; } + if(pmeinfo->action == KNI_ACTION_BYPASS){ + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); + return APP_STATE_FAWPKT | APP_STATE_GIVEME; + } //TODO: client hello如果跨包怎么办?client hello后面一个包先到,这个包该丢掉还是bypass //此时 action = KNI_ACTION_UNKNOWN, 说明还没收到第一个数据包 // syn/ack包 @@ -238,6 +551,7 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein if(stream->dir != DIR_DOUBLE){ KNI_LOG_INFO(logger, "stream dir is %d, bypass", stream->dir); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); + pmeinfo->tfe_release = 1; return APP_STATE_FAWPKT | APP_STATE_DROPME; } //三次握手成功才算一个流 @@ -251,21 +565,32 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 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); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_UNKNOWN_STM], 0, FS_OP_ADD, 1); + pmeinfo->tfe_release = 1; return APP_STATE_FAWPKT | APP_STATE_DROPME; } //protocol = KNI_PROTOCOL_SSL/KNI_PROTOCOL_HTTP, 判断action, action返回值: KNI_ACTION_INTERCEPT/KNI_ACTION_BYPASS if(pmeinfo->protocol == KNI_PROTOCOL_SSL){ + memcpy(pmeinfo->sni, result->domain, result->domain_len); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SSL_STM], 0, FS_OP_ADD, 1); } if(pmeinfo->protocol == KNI_PROTOCOL_HTTP){ + memcpy(pmeinfo->host, result->domain, result->domain_len); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_HTTP_STM], 0, FS_OP_ADD, 1); } - pmeinfo->action = get_action((struct ipaddr*)(&stream->addr), result->domain, result->domain_len, thread_seq); + pmeinfo->action = get_action((struct ipaddr*)(&stream->addr), result->domain, result->domain_len, thread_seq, &(pmeinfo->policy_id)); + //输出maat拦截日志 + char stream_addr[KNI_SYMBOL_MAX] = ""; + kni_stream_addr_trans((struct ipaddr*)(&stream->addr), stream_addr, sizeof(stream_addr)); + char domain_str[KNI_DOMAIN_MAX] = ""; + memcpy(domain_str, result->domain, result->domain_len); + KNI_LOG_DEBUG(logger, "get_action: %s, %s, policy_id = %d, action = %s", + stream_addr, domain_str, pmeinfo->policy_id, pmeinfo->action == KNI_ACTION_BYPASS ? "bypass" : "intercept"); FREE(&result); + //如果是bypass if(pmeinfo->action == KNI_ACTION_BYPASS){ FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 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_DROPME; + return APP_STATE_FAWPKT | APP_STATE_GIVEME; } //TODO: 这块比较奇怪, 收到client hello, 但是没有syn/ack包, 直接bypass了 if(pmeinfo->client_tcpopt == NULL || pmeinfo->server_tcpopt == NULL){ @@ -274,25 +599,35 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SA_EXP], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 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->tfe_release = 1; return APP_STATE_FAWPKT | APP_STATE_DROPME; } //action = KNI_ACTION_INTERCEPT, 带上控制信息发送给qq, 要修改ip, tcp的校验和 - buf = tcp_restore_info_header_add(pmeinfo, pktinfo, &len); - send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq); + buf = add_cmsg_to_packet(pmeinfo, pktinfo, &len); + send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id); FREE(&buf); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1); 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 close_opstate(){ +static char close_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, int thread_seq){ + //close 数据也要发送给tfe + //void *logger = g_kni_handle->logger; + char *buf = (char*)pktinfo->iphdr; + int len = pktinfo->ip_totlen; + if(pmeinfo->action == KNI_ACTION_INTERCEPT){ + send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1); + return APP_STATE_DROPPKT | APP_STATE_DROPME; + } FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); return APP_STATE_FAWPKT | APP_STATE_DROPME; } //从syn包开始回调 -extern "C" char kni_tcpall_entry(const struct streaminfo* stream, void** pme, int thread_seq, const void* a_packet){ - void *logger = g_kni_handle->logger; +extern "C" char kni_tcpall_entry(const struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){ + void *logger = g_kni_handle->local_logger; //KNI_LOG_DEBUG(logger, "call kni_tcpall_entry"); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TOT_PKT], 0, FS_OP_ADD, 1); //当前包bypass, 剩下包bypass @@ -321,14 +656,20 @@ extern "C" char kni_tcpall_entry(const struct streaminfo* stream, void** pme, in int ret; switch(stream->pktstate){ case OP_STATE_PENDING: - *pme = pmeinfo = pme_info_new(); + *pme = pmeinfo = pme_info_new(stream, thread_seq, logger); + ret = MESA_htable_add(g_kni_handle->traceid2pme_htable, (const unsigned char *)(pmeinfo->stream_trace_id), + strlen(pmeinfo->stream_trace_id), (const void*)pmeinfo); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_htable: failed at MESA_htable_add," + "table is traceid2pme_htable, key is %s", pmeinfo->stream_trace_id); + } ret = pending_opstate(stream, pmeinfo, pktinfo); break; case OP_STATE_DATA: ret = data_opstate(stream, pmeinfo, pktinfo, thread_seq); break; case OP_STATE_CLOSE: - ret = close_opstate(); + ret = close_opstate(stream, pmeinfo, pktinfo, thread_seq); break; default: ret = APP_STATE_FAWPKT | APP_STATE_GIVEME; @@ -339,6 +680,8 @@ extern "C" char kni_tcpall_entry(const struct streaminfo* stream, void** pme, in } FREE(&pktinfo); if((ret & APP_STATE_DROPME)){ + //sendlog_to_kafka(pmeinfo, logger); + pmeinfo->sapp_release = 1; pme_info_destroy(pmeinfo); *pme = NULL; } @@ -350,7 +693,7 @@ void http_project_free(int thread_seq, void *project_req_value){ } static int http_project_init(){ - void *logger = g_kni_handle->logger; + 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); @@ -390,21 +733,28 @@ static void kni_marsio_destroy(struct kni_marsio_handle *handle){ if(handle->instance != NULL){ marsio_destory(handle->instance); } + for(int i = 0; i < TFE_COUNT_MAX; i++){ + FREE(&handle->tfe_instance_list[i]); + } } FREE(&handle); + handle = NULL; } -void * thread_tfe_receiver(void* args){ - struct tfe_receiver_args *_args = (struct tfe_receiver_args*)args; +void* thread_tfe_data_receiver(void *args){ + struct thread_tfe_data_receiver_args *_args = (struct thread_tfe_data_receiver_args*)args; //void *logger = _args->logger; struct kni_marsio_handle *marsio_handle = _args->marsio_handle; + int tfe_id = _args->tfe_id; + struct mr_vdev *dev_eth_handler = marsio_handle->tfe_instance_list[tfe_id]->dev_eth_handler; + FREE(&args); marsio_buff_t * rx_buff[BURST_MAX]; int nr_burst = 1; //实际上是网卡队列id int thread_seq = 0; while(true){ //从tfe上收 - int ret = marsio_recv_burst(marsio_handle->dev_eth_handler, thread_seq, rx_buff, nr_burst); + int ret = marsio_recv_burst(dev_eth_handler, thread_seq, rx_buff, nr_burst); if(ret <= 0){ continue; } @@ -420,99 +770,325 @@ void * thread_tfe_receiver(void* args){ return NULL; } +static int wrapped_kni_cmsg_get(struct pme_info *pmeinfo, struct kni_cmsg *cmsg, uint16_t type, uint16_t value_size_max, void *logger){ + uint16_t value_size = 0; + unsigned char *value = NULL; + int ret = kni_cmsg_get(cmsg, type, &value_size, &value); + if(ret < 0){ + KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type is %d, ret is %d", type, ret); + return -1; + } + if(value_size > value_size_max){ + KNI_LOG_ERROR(logger, "kni_cmsg_get: type is %s, size is %d, which should <= %d", type, value_size, value_size_max); + return -1; + } + switch(type) + { + case TFE_CMSG_SSL_INTERCEPT_STATE: + memcpy((char*)&(pmeinfo->intercept_state), value, value_size); + break; + case TFE_CMSG_SSL_UPSTREAM_LATENCY: + memcpy((char*)&(pmeinfo->ssl_server_side_latency), value, value_size); + break; + case TFE_CMSG_SSL_DOWNSTREAM_LATENCY: + memcpy((char*)&(pmeinfo->ssl_client_side_latency), value, value_size); + break; + case TFE_CMSG_SSL_UPSTREAM_VERSION: + memcpy(pmeinfo->ssl_server_side_version, value, value_size); + break; + case TFE_CMSG_SSL_DOWNSTREAM_VERSION: + memcpy(pmeinfo->ssl_client_side_version, value, value_size); + break; + case TFE_CMSG_SSL_PINNING_STATE: + memcpy((char*)&(pmeinfo->pinningst), value, value_size); + break; + case TFE_CMSG_SSL_CERT_VERIFY: + memcpy((char*)&(pmeinfo->ssl_cert_verify), value, value_size); + break; + case TFE_CMSG_SSL_ERROR: + memcpy((char*)&(pmeinfo->ssl_error), value, value_size); + break; + default: + break; + } + return 0; +} + +static long traceid2pme_htable_search_cb(void *data, const uchar *key, uint size, void *user_args){ + struct traceid2pme_search_cb_args *args = (struct traceid2pme_search_cb_args*)user_args; + void *logger = args->logger; + struct kni_cmsg *cmsg = args->cmsg; + struct pme_info *pmeinfo = (struct pme_info*)data; + if(pmeinfo != NULL){ + wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_INTERCEPT_STATE, sizeof(pmeinfo->intercept_state), logger); + wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_UPSTREAM_LATENCY, sizeof(pmeinfo->ssl_server_side_latency), logger); + wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_DOWNSTREAM_LATENCY, sizeof(pmeinfo->ssl_client_side_latency), logger); + wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_UPSTREAM_VERSION, sizeof(pmeinfo->ssl_server_side_version) - 1, logger); + wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_DOWNSTREAM_VERSION, sizeof(pmeinfo->ssl_client_side_version) - 1, logger); + wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_PINNING_STATE, sizeof(pmeinfo->pinningst), logger); + 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); + pmeinfo->tfe_release = 1; + int ret = MESA_htable_del(g_kni_handle->traceid2pme_htable, (const unsigned char *)pmeinfo->stream_trace_id, + sizeof(pmeinfo->stream_trace_id), NULL); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_htable: failed at del, table is %s, key is %s, ret is %d", + "traceid2pme_htable", pmeinfo->stream_trace_id, ret); + } + } + return 0; +} + +void* thread_tfe_cmsg_receiver(void *args){ + struct thread_tfe_cmsg_receiver_args *_args = (struct thread_tfe_cmsg_receiver_args*)args; + const char *profile = _args->profile; + const char *section = "tfe_cmsg_receiver"; + void *logger = _args->logger; + char listen_eth[INET_ADDRSTRLEN]; + uint32_t listen_ip; + int listen_port = -1; + char buff[KNI_MTU]; + int sockfd; + 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); + 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); + goto error_out; + } + KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n listen_eth: %s\n listen_port: %d", + section, listen_eth, listen_port); + FREE(&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)); + 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); + goto error_out; + } + server_addr.sin_family = AF_INET; // IPv4 + server_addr.sin_addr.s_addr = listen_ip; + server_addr.sin_port = htons(listen_port); + //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)); + goto error_out; + } + //receive + while(true){ + socklen_t client_len = sizeof(client_addr); + 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)); + continue; + } + KNI_LOG_DEBUG(logger, "recv udp data: recv_len is %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); + continue; + } + //get stream_trace_id + unsigned char *stream_trace_id = NULL; + uint16_t value_size; + ret = kni_cmsg_get(cmsg, TFE_CMSG_STREAM_TRACE_ID, &value_size, &stream_trace_id); + if(ret < 0){ + KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type is %d, ret is %d", TFE_CMSG_STREAM_TRACE_ID, ret); + continue; + } + //get pme + long cb_ret = -1; + struct traceid2pme_search_cb_args cb_args; + memset((void*)&cb_args, sizeof(cb_args), 0); + cb_args.cmsg = cmsg; + cb_args.logger = logger; + MESA_htable_search_cb(g_kni_handle->traceid2pme_htable, (const unsigned char *)stream_trace_id, + strlen((char*)stream_trace_id), traceid2pme_htable_search_cb, &cb_args, &cb_ret); + } + return NULL; + +error_out: + if(sockfd >= 0){ + close(sockfd); + } + return NULL; +} static struct kni_marsio_handle* kni_marsio_init(const char* profile){ - void *logger = g_kni_handle->logger; + void *logger = g_kni_handle->local_logger; const char* section = "marsio"; char appsym[KNI_SYMBOL_MAX]; - char dev_eth_symbol[KNI_SYMBOL_MAX]; char dev_vxlan_symbol[KNI_SYMBOL_MAX]; - MESA_load_profile_string_def(profile, section, "appsym", appsym, sizeof(appsym), "unknown"); - MESA_load_profile_string_def(profile, section, "dev_eth_symbol", dev_eth_symbol, sizeof(dev_eth_symbol), "unknown"); - MESA_load_profile_string_def(profile, section, "dev_vxlan_symbol", dev_vxlan_symbol, sizeof(dev_vxlan_symbol), "unknown"); - KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n appsym: %s\n dev_eth_symbol: %s\n dev_vxlan_symbol: %s", - section, appsym, dev_eth_symbol, dev_vxlan_symbol); - struct mr_instance *instance = marsio_create(); - if(instance == NULL){ - KNI_LOG_ERROR(logger, "Failed at create marsio instance"); - return NULL; - } + char src_mac_addr_str[KNI_SYMBOL_MAX]; unsigned int opt_value = 1; - marsio_option_set(instance, MARSIO_OPT_EXIT_WHEN_ERR, &opt_value, sizeof(opt_value)); + int tfe_count; + 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 tfe_instance *tfe_inst = NULL; + struct kni_marsio_handle *handle = NULL; + 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); + 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); + goto error_out; + } + KNI_LOG_INFO(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); + mr_inst = marsio_create(); + if(mr_inst == NULL){ + KNI_LOG_ERROR(logger, "Failed at create marsio instance"); + goto error_out; + } + handle = ALLOC(struct kni_marsio_handle, 1); + handle->instance = mr_inst; + ret = sscanf(src_mac_addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &(handle->src_mac_addr[0]), &(handle->src_mac_addr[1]), + &(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); + goto error_out; + } + marsio_option_set(mr_inst, MARSIO_OPT_EXIT_WHEN_ERR, &opt_value, sizeof(opt_value)); //uint64_t cpu_mask = 0x3c; //?? //marsio_option_set(handle->instance, MARSIO_OPT_THREAD_MASK, &cpu_mask, sizeof(cpu_mask)); - marsio_init(instance, appsym); + marsio_init(mr_inst, appsym); //eth_handler有一个线程收, g_iThreadNum个线程发 - struct mr_vdev *dev_eth_handler = marsio_open_device(instance, dev_eth_symbol, 1, g_iThreadNum); - if(dev_eth_handler == NULL){ - KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol is %s", dev_eth_symbol); - return NULL; + tfe_count = g_kni_handle->tfe_count; + for(int i = 0; i < tfe_count; i++){ + //load tfe conf + char _section[KNI_SYMBOL_MAX]; + char mac_addr_str[KNI_SYMBOL_MAX]; + char dev_eth_symbol[KNI_SYMBOL_MAX]; + snprintf(_section, sizeof(_section), "tfe%d", i); + 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); + goto error_out; + } + tfe_inst = ALLOC(struct tfe_instance, 1); + //转化mac地址, ff:ee:dd:cc:bb:aa ---> 0xff 0xee 0xdd 0xcc 0xbb 0xaa + ret = sscanf(mac_addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &tfe_inst->mac_addr[0], &tfe_inst->mac_addr[1], + &tfe_inst->mac_addr[2], &tfe_inst->mac_addr[3], + &tfe_inst->mac_addr[4], &tfe_inst->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); + 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); + goto error_out; + } + KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n mac_addr: %s\n dev_eth_symbol: %s", + _section, mac_addr_str, dev_eth_symbol); + //handler + dev_eth_handler = marsio_open_device(mr_inst, dev_eth_symbol, 1, g_iThreadNum); + if(dev_eth_handler == NULL){ + KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol is %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); + goto error_out; + } + //tfe_instance + tfe_inst->dev_eth_handler = dev_eth_handler; + tfe_inst->dev_eth_sendpath = dev_eth_sendpath; + handle->tfe_instance_list[i] = tfe_inst; } //vxlan_handler有0个线程收, 1个线程发 - struct mr_vdev *dev_vxlan_handler = marsio_open_device(instance, dev_vxlan_symbol, 0, 1); + dev_vxlan_handler = marsio_open_device(mr_inst, dev_vxlan_symbol, 0, 1); if(dev_vxlan_handler == NULL){ KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol is %s", dev_vxlan_symbol); - return NULL; + goto error_out; } - struct mr_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); - return NULL; - } - struct mr_sendpath * dev_vxlan_sendpath = marsio_sendpath_create_by_vdev(dev_vxlan_handler); + 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); - return NULL; - } - struct kni_marsio_handle *handle = ALLOC(struct kni_marsio_handle, 1); - handle->instance = instance; - handle->dev_eth_handler = dev_eth_handler; - handle->dev_eth_sendpath = dev_eth_sendpath; - handle->dev_vxlan_handler = dev_vxlan_handler; + goto error_out; + } handle->dev_vxlan_sendpath = dev_vxlan_sendpath; //暂时不用调 //marsio_thread_init(mr_instance); - - - //创建线程从tfe收包然后打上标签发送给vxlan_user - pthread_t thread_id; - struct tfe_receiver_args *args = ALLOC(struct tfe_receiver_args, 1); - args->logger = logger; - args->marsio_handle = handle; - int ret = pthread_create(&thread_id, NULL, thread_tfe_receiver, (void *)args); - if(unlikely(ret != 0)){ - KNI_LOG_ERROR(logger, "Failed at pthread_create, name is thread_tfe_receiver, ret is %d", ret); - exit(EXIT_FAILURE); - } - return handle; + +error_out: + kni_marsio_destroy(handle); + return NULL; +} + +static void fs_destroy(struct kni_field_stat_handle *fs_handle){ + if(fs_handle != NULL){ + FS_stop(&(fs_handle->handle)); + } + FREE(&fs_handle); } static struct kni_field_stat_handle * fs_init(const char *profile){ - void *logger = g_kni_handle->logger; + void *logger = g_kni_handle->local_logger; const char *section = "field_stat"; char stat_path[KNI_PATH_MAX]; - MESA_load_profile_string_def(profile, section, "stat_path", stat_path, KNI_PATH_MAX, "unknown"); + struct kni_field_stat_handle *fs_handle = NULL; + screen_stat_handle_t handle = NULL; + const char *app_name = "fs2_kni"; + 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); + goto error_out; + } KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n stat_path: %s\n", "field_stat", stat_path); - screen_stat_handle_t handle = FS_create_handle(); + handle = FS_create_handle(); if(handle == NULL){ KNI_LOG_ERROR(logger, "Failed at create FS_create_handle"); - return NULL; + goto error_out; } - const char* app_name = "fs2_kni"; + fs_handle = ALLOC(struct kni_field_stat_handle, 1); + fs_handle->handle = handle; FS_set_para(handle, APP_NAME, app_name, strlen(app_name) + 1); FS_set_para(handle, OUTPUT_DEVICE, stat_path, strlen(stat_path)+1); - int value=0; + value = 0; FS_set_para(handle, FLUSH_BY_DATE, &value, sizeof(value)); - value=1; + value = 1; FS_set_para(handle, PRINT_MODE, &value, sizeof(value)); - value=1; + value = 1; FS_set_para(handle, CREATE_THREAD, &value, sizeof(value)); - value=5; + value = 5; FS_set_para(handle, STAT_CYCLE, &value, sizeof(value)); - value=4096; + value = 4096; FS_set_para(handle, MAX_STAT_FIELD_NUM, &value, sizeof(value)); - struct kni_field_stat_handle *fs_handle = ALLOC(struct kni_field_stat_handle, 1); + fs_handle = ALLOC(struct kni_field_stat_handle, 1); fs_handle->handle = handle; fs_handle->fields[KNI_FIELD_TOT_PKT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tot_pkt"); fs_handle->fields[KNI_FIELD_BYP_PKT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_pkt"); @@ -527,60 +1103,179 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ fs_handle->fields[KNI_FIELD_INTCP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_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_UNKNOWN_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "unknown_stm"); fs_handle->handle = handle; FS_start(handle); return fs_handle; + +error_out: + fs_destroy(fs_handle); + return NULL; +} + + +extern "C" void kni_destroy(struct kni_handle *handle){ + if(handle != NULL){ + + } + FREE(&handle); + handle = NULL; +} + +static void traceid2pme_htable_data_free_cb(void *data){ + struct pme_info *pmeinfo = (struct pme_info*)data; + pme_info_destroy(pmeinfo); +} + +//eliminate_type: 0:FIFO; 1:LRU +//ret: 1: the item can be eliminated; 0: the item can't be eliminated +static int traceid2pme_htable_expire_notify_cb(void *data, int eliminate_type){ + struct pme_info *pmeinfo = (struct pme_info*)data; + if(pmeinfo->sapp_release == 0){ + return 0; + } + pmeinfo->tfe_release = 1; + return 1; } extern "C" int kni_init(){ - g_kni_handle = ALLOC(struct kni_handle, 1); const char *profile = "./conf/kni/kni.conf"; const char *section = "global"; - //init logger - char log_path[KNI_PATH_MAX]; - MESA_load_profile_string_def(profile, section, "log_path", log_path, sizeof(log_path), "unknown"); - int log_level; - MESA_load_profile_int_def(profile, section, "log_level", &log_level, 10); - void *logger = MESA_create_runtime_log_handle(log_path, log_level); - if (unlikely(logger == NULL)) - { - printf("Failed at create logger: %s, exit", log_path); - exit(EXIT_FAILURE); + char log_path[KNI_PATH_MAX] = ""; + int tfe_count = 0; + char local_eth[KNI_SYMBOL_MAX] = ""; + struct kni_send_logger *send_logger = NULL; + struct kni_field_stat_handle *fs_handle = NULL; + int id = -1; + void *local_logger = NULL; + int log_level = -1; + pthread_t thread_id = -1; + struct thread_tfe_cmsg_receiver_args *cmsg_receiver_args; + MESA_htable_handle traceid2pme_htable = 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); + goto error_out; } - KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n log_path: %s\n log_level: %d", section, log_path, log_level); - g_kni_handle->logger = logger; + 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); + goto error_out; + } + local_logger = MESA_create_runtime_log_handle(log_path, log_level); + if (unlikely(local_logger == NULL)){ + printf("Failed at create logger: %s", log_path); + goto error_out; + } + ret = MESA_load_profile_int_nodef(profile, section, "tfe_count", &tfe_count); + if(ret < 0){ + KNI_LOG_ERROR(local_logger, "MESA_prof_load: tfe_count not set, profile is %s, section is %s", profile, section); + goto error_out; + } + if(tfe_count > TFE_COUNT_MAX){ + KNI_LOG_ERROR(local_logger, "tfe_count is %d, exceed the max_tfe_count %d", tfe_count, TFE_COUNT_MAX); + goto error_out; + } + if(tfe_count <= 0){ + KNI_LOG_ERROR(local_logger, "tfe_count is %d, <= 0", tfe_count); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "local_eth", local_eth, sizeof(local_eth)); + if(ret < 0){ + printf("MESA_prof_load: local_eth not set, profile is %s, section is %s", profile, section); + goto error_out; + } + KNI_LOG_INFO(local_logger, "MESA_prof_load, [%s]:\n log_path: %s\n log_level: %d\n tfe_count: %d\n local_eth: %s", + section, log_path, log_level, tfe_count, local_eth); + g_kni_handle = ALLOC(struct kni_handle, 1); + g_kni_handle->local_logger = local_logger; + g_kni_handle->tfe_count = tfe_count; //init http_project - int id = http_project_init(); + id = http_project_init(); if(id < 0){ - KNI_LOG_ERROR(logger, "Failed at init http project, exit. ret is %d", id); - exit(EXIT_FAILURE); + KNI_LOG_ERROR(local_logger, "Failed at init http project, ret is %d", id); + goto error_out; } g_kni_handle->http_project_id = id; //init marsio g_kni_handle->marsio_handle = kni_marsio_init(profile); if(g_kni_handle->marsio_handle == NULL){ - KNI_LOG_ERROR(logger, "Failed at init marsio, exit"); - exit(EXIT_FAILURE); + KNI_LOG_ERROR(local_logger, "Failed at init marsio"); + goto error_out; + } + + //创建线程从tfe收包然后打上标签发送给vxlan_user + for(int i = 0; i < tfe_count; 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->tfe_id = 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, ret is %d", ret); + FREE(&args); + goto error_out; + } + } + + //创建线程从tfe收取cmsg控制信息 + cmsg_receiver_args = ALLOC(struct thread_tfe_cmsg_receiver_args, 1); + cmsg_receiver_args->logger = local_logger; + memcpy(cmsg_receiver_args->profile, profile, strlen(profile)); + 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, ret is %d", ret); + FREE(&cmsg_receiver_args); + goto error_out; } //init maat - g_kni_handle->maat_handle = kni_maat_init(profile, logger); + g_kni_handle->maat_handle = kni_maat_init(profile, local_logger); if(g_kni_handle->maat_handle == NULL){ - KNI_LOG_ERROR(logger, "Failed at init maat, exit"); - exit(EXIT_FAILURE); + KNI_LOG_ERROR(local_logger, "Failed at init maat"); + goto error_out; } //init_filedstat - struct kni_field_stat_handle *fs_handle = fs_init(profile); + fs_handle = fs_init(profile); if(fs_handle == NULL){ - KNI_LOG_ERROR(logger, "Failed at init field_stat"); + KNI_LOG_ERROR(local_logger, "Failed at init field_stat"); + goto error_out; } g_kni_fs_handle = fs_handle; + //init local_ipv4 + ret = kni_ipv4_addr_get_by_eth(local_eth, &(g_kni_handle->local_ipv4)); + if(ret < 0){ + KNI_LOG_ERROR(local_logger, "Failed at get bind ipv4 addr, eth is %s", local_eth); + goto error_out; + } + + //init kni_send_logger + send_logger = kni_send_logger_init(profile, local_logger); + if(send_logger == NULL){ + KNI_LOG_ERROR(local_logger, "Failed at init kni_send_logger", local_eth); + goto error_out; + } + g_kni_handle->send_logger = send_logger; + + //init traceid2pme_htable + traceid2pme_htable = kni_create_htable(profile, "traceid2pme_htable", (void*)traceid2pme_htable_data_free_cb, + (void*)traceid2pme_htable_expire_notify_cb, local_logger); + if(traceid2pme_htable == NULL){ + KNI_LOG_ERROR(local_logger, "Failed at create traceid2pme_htable"); + goto error_out; + } + g_kni_handle->traceid2pme_htable = traceid2pme_htable; return 0; + +error_out: + kni_destroy(g_kni_handle); + return -1; } \ No newline at end of file diff --git a/entry/src/kni_maat.cpp b/entry/src/kni_maat.cpp index 5293117..b1d316c 100644 --- a/entry/src/kni_maat.cpp +++ b/entry/src/kni_maat.cpp @@ -2,8 +2,16 @@ #include "kni_maat.h" extern int g_iThreadNum; + int g_maat_default_action = -1; +struct kni_maat_handle{ + Maat_feather_t feather; + int tableid_intercept_ip; + int tableid_intercept_domain; + void *logger; +}; + void kni_maat_destroy(struct kni_maat_handle *handle){ if(handle != NULL){ if(handle->feather != NULL){ @@ -42,76 +50,125 @@ struct kni_maat_handle* kni_maat_init(const char* profile, void *logger){ char tablename_intercept_ip[KNI_SYMBOL_MAX]; char tablename_intercept_domain[KNI_SYMBOL_MAX]; char compile_alias[KNI_SYMBOL_MAX]; - MESA_load_profile_int_def(profile, section, "readconf_mode", &readconf_mode, KNI_MAAT_READCONF_IRIS); - MESA_load_profile_string_def(profile, section, "tableinfo_path", tableinfo_path, sizeof(tableinfo_path), "unknown"); - MESA_load_profile_string_def(profile, section, "tablename_intercept_ip", tablename_intercept_ip, sizeof(tablename_intercept_ip), "unknown"); - MESA_load_profile_string_def(profile, section, "tablename_intercept_domain", tablename_intercept_domain, sizeof(tablename_intercept_domain), "unknown"); - MESA_load_profile_string_def(profile, section, "compile_alias", compile_alias, sizeof(compile_alias), "unknown"); + char maatjson_path[KNI_PATH_MAX]; + char redis_ip[INET_ADDRSTRLEN]; + int redis_port; + int redis_index; + Maat_feather_t feather = NULL; + int tableid_intercept_ip = -1; + int tableid_intercept_domain = -1; + struct kni_maat_handle *handle = NULL; + int ret = MESA_load_profile_int_nodef(profile, section, "readconf_mode", &readconf_mode); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: readconf_mode not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "tableinfo_path", tableinfo_path, sizeof(tableinfo_path)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: tableinfo_path not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "tablename_intercept_ip", tablename_intercept_ip, sizeof(tablename_intercept_ip)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: tablename_intercept_ip not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "tablename_intercept_domain", tablename_intercept_domain, sizeof(tablename_intercept_domain)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: tablename_intercept_domain not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "compile_alias", compile_alias, sizeof(compile_alias)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: compile_alias not set, profile is %s, section is %s", profile, section); + goto error_out; + } KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n readconf_mode: %d\n tableinfo_path: %s\n tablename_intercept_ip: %s\n tablename_intercept_domain: %s\n" "compile_alias: %s\n", section, readconf_mode, tableinfo_path, tablename_intercept_ip, tablename_intercept_domain, compile_alias); - Maat_feather_t feather = Maat_feather(g_iThreadNum, tableinfo_path, logger); + feather = Maat_feather(g_iThreadNum, 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); return NULL; } - if(readconf_mode == KNI_MAAT_READCONF_JSON){ - char maatjson_path[KNI_PATH_MAX]; - MESA_load_profile_string_def(profile, section, "maatjson_path", maatjson_path, sizeof(maatjson_path), "unknown"); - KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n maatjson_path: %s", section, maatjson_path); - Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, maatjson_path, strlen(maatjson_path)); + switch(readconf_mode){ + case KNI_MAAT_READCONF_JSON: + ret = MESA_load_profile_string_nodef(profile, section, "maatjson_path", maatjson_path, sizeof(maatjson_path)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: maatjson_path not set, profile is %s, section is %s", profile, section); + goto error_out; + } + KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n maatjson_path: %s", section, maatjson_path); + Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, maatjson_path, strlen(maatjson_path)); + break; + case KNI_MAAT_READCONF_IRIS: + break; + case KNI_MAAT_READCONF_REDIS: + ret = MESA_load_profile_string_nodef(profile, section, "redis_ip", redis_ip, sizeof(redis_ip)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: redis_ip not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_int_nodef(profile, section, "redis_port", &redis_port); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: redis_port not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_int_nodef(profile, section, "redis_index", &redis_index); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: redis_index not set, profile is %s, section is %s", profile, section); + goto error_out; + } + KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n redis_ip: %s\n redis_port: %d\n redis_index: %d", + section, redis_ip, redis_port, redis_index); + Maat_set_feather_opt(feather, MAAT_OPT_REDIS_IP, (void*)redis_ip, strlen(redis_ip) + 1); + Maat_set_feather_opt(feather, MAAT_OPT_REDIS_PORT, (void*)&redis_port, sizeof(redis_port)); + Maat_set_feather_opt(feather, MAAT_OPT_REDIS_INDEX, (void*)&redis_index, sizeof(redis_index)); + break; + default: + break; } - if(readconf_mode == KNI_MAAT_READCONF_IRIS){ - //TODO - } - if(readconf_mode == KNI_MAAT_READCONF_REDIS){ - char redis_ip[KNI_SYMBOL_MAX]; - int redis_port; - int redis_index; - MESA_load_profile_string_def(profile, section, "redis_ip", redis_ip, sizeof(redis_ip), "unknown"); - MESA_load_profile_int_def(profile, section, "redis_port", &redis_port, -1); - MESA_load_profile_int_def(profile, section, "redis_index", &redis_index, -1); - KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n redis_ip: %s\n redis_port: %s\n redis_index: %d", - section, redis_ip, redis_port, redis_index); - Maat_set_feather_opt(feather, MAAT_OPT_REDIS_IP, (void*)redis_ip, strlen(redis_ip) + 1); - Maat_set_feather_opt(feather, MAAT_OPT_REDIS_PORT, (void*)&redis_port, sizeof(redis_port)); - Maat_set_feather_opt(feather, MAAT_OPT_REDIS_INDEX, (void*)&redis_index, sizeof(redis_index)); - } - int ret = Maat_initiate_feather(feather); + ret = Maat_initiate_feather(feather); if(ret < 0){ KNI_LOG_ERROR(logger, "Failed at Maat_initiate_feather"); - return NULL; + goto error_out; } - int tableid_intercept_ip = Maat_table_register(feather, tablename_intercept_ip); - int tableid_intercept_domain = Maat_table_register(feather, tablename_intercept_domain); + tableid_intercept_ip = Maat_table_register(feather, tablename_intercept_ip); + tableid_intercept_domain = Maat_table_register(feather, tablename_intercept_domain); if(tableid_intercept_ip < 0){ KNI_LOG_ERROR(logger, "Failed at Maat_table_register, tablename is %d, ret is %d", tablename_intercept_ip, tableid_intercept_ip); - return NULL; + goto error_out; } if(tableid_intercept_domain < 0){ KNI_LOG_ERROR(logger, "Failed at Maat_table_register, tablename is %d, ret is %d", tablename_intercept_domain, tableid_intercept_domain); - return NULL; + goto error_out; } - struct kni_maat_handle *handle = ALLOC(struct kni_maat_handle, 1); ret = Maat_rule_get_ex_new_index(feather, compile_alias, compile_ex_param_new, compile_ex_param_free, compile_ex_param_dup, 0, logger); if(ret < 0){ KNI_LOG_ERROR(logger, "Failed at Maat_rule_get_ex_new_index, ret is %d", ret); kni_maat_destroy(handle); - return NULL; + goto error_out; } - handle->feather = feather; handle->tableid_intercept_ip = tableid_intercept_ip; handle->tableid_intercept_domain = tableid_intercept_domain; handle->logger = logger; return handle; + +error_out: + kni_maat_destroy(handle); + return NULL; } -static int maat_process_scan_result(struct kni_maat_handle *handle, int num, struct Maat_rule_t *result){ +static int maat_process_scan_result(struct kni_maat_handle *handle, int num, struct Maat_rule_t *result, int *policy_id){ //void *logger = handle->logger; int action = g_maat_default_action; + *policy_id = 0; //默认动作是编译表中policy_id=0的字段,所以默认policy_id=0; for(int i = 0; i < num; i++){ action = result[i].action; + *policy_id = result[i].config_id; if(action == KNI_ACTION_BYPASS){ return action; } @@ -121,7 +178,7 @@ static int maat_process_scan_result(struct kni_maat_handle *handle, int num, str //TODO: Maat_rule_get_ex_new_index compile_ex_param_new: config_id = 0, 取action即为全局变量, 一旦配置更新就回调, tableinfo怎么写,回调表, 编译配置表 -int kni_maat_scan_ip(struct kni_maat_handle *handle, struct ipaddr *addr, int thread_seq){ +int kni_maat_scan_ip(struct kni_maat_handle *handle, struct ipaddr *addr, int thread_seq, int *policy_id){ //printf("default action is %d\n", g_maat_default_action); void *logger = handle->logger; struct Maat_rule_t result[KNI_MAAT_RULE_NUM_MAX]; @@ -132,17 +189,17 @@ int kni_maat_scan_ip(struct kni_maat_handle *handle, struct ipaddr *addr, int th KNI_LOG_ERROR(logger, "Failed at Maat_scan_proto_addr, ret is %d", ret); return g_maat_default_action; } - int action = maat_process_scan_result(handle, ret, result); + int action = maat_process_scan_result(handle, ret, result, policy_id); //for debug - char saddr[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &(addr->v4->saddr), saddr, INET_ADDRSTRLEN); - KNI_LOG_DEBUG(logger, "ip is %s, ret is %d, action is %d\n", saddr, ret, action); - + char stream_addr[KNI_SYMBOL_MAX] = ""; + kni_stream_addr_trans(addr, stream_addr, sizeof(stream_addr)); + KNI_LOG_DEBUG(logger, "maat_scan_ip, %s, policy_id = %d, action = %s\n", + stream_addr, *policy_id, action == KNI_ACTION_BYPASS ? "bypss" : "intercept"); return action; } -int kni_maat_scan_domain(struct kni_maat_handle* handle, char *domain, int domain_len, int thread_seq){ +int kni_maat_scan_domain(struct kni_maat_handle* handle, char *domain, int domain_len, int thread_seq, int *policy_id){ void *logger = handle->logger; struct Maat_rule_t result[KNI_MAAT_RULE_NUM_MAX]; //必须要初始化为NULL, 不懂为什么 @@ -153,14 +210,14 @@ int kni_maat_scan_domain(struct kni_maat_handle* handle, char *domain, int domai KNI_LOG_ERROR(logger, "Failed at Maat_full_scan_string, ret is %d", ret); return g_maat_default_action; } - int action = maat_process_scan_result(handle, ret, result); + int action = maat_process_scan_result(handle, ret, result, policy_id); //for debug char domain1[100] = ""; memcpy(domain1, domain, domain_len); domain1[domain_len] = '\0'; - KNI_LOG_DEBUG(logger, "domain is %s, ret is %d, action is %d\n", domain, ret, action); - + KNI_LOG_DEBUG(logger, "maat_scan_domain: %s, policy_id = %d, action = %s\n", + domain, *policy_id, action == KNI_ACTION_BYPASS ? "bypss" : "intercept"); return action; } diff --git a/entry/src/kni_send_logger.cpp b/entry/src/kni_send_logger.cpp new file mode 100644 index 0000000..4b22b90 --- /dev/null +++ b/entry/src/kni_send_logger.cpp @@ -0,0 +1,149 @@ +#include "kni_utils.h" +#include "kni_send_logger.h" +#include "librdkafka/rdkafka.h" + +struct kni_send_logger{ + int sendlog_switch; + rd_kafka_t *kafka_handle; + rd_kafka_topic_t *kafka_topic; + void *local_logger; +}; + +static rd_kafka_t* kafka_init(const char *profile, void *logger){ + rd_kafka_t *kafka_handle = NULL; + rd_kafka_conf_t *rdkafka_conf = NULL; + char kafka_errstr[1024]; + const char *section = "kafka"; + char queue_buffering_max_messages[KNI_SYMBOL_MAX] = ""; + char topic_metadata_refresh_interval_ms[KNI_SYMBOL_MAX] = ""; + char security_protocol[KNI_SYMBOL_MAX] = ""; + int ret = MESA_load_profile_string_nodef(profile, section, "queue.buffering.max.messages", + queue_buffering_max_messages, sizeof(queue_buffering_max_messages)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: queue.buffering.max.messages not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "topic.metadata.refresh.interval.ms", + topic_metadata_refresh_interval_ms, sizeof(topic_metadata_refresh_interval_ms)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: topic.metadata.refresh.interval.ms not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "security.protocol", security_protocol, sizeof(security_protocol)); + if(ret < 0){ + KNI_LOG_ERROR(logger, "MESA_prof_load: security.protocol not set, profile is %s, section is %s", profile, section); + goto error_out; + } + KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n queue.buffering.max.messages: %s\n topic.metadata.refresh.interval.ms: %s\n" + "security.protocol: %s", "kafka", queue_buffering_max_messages, topic_metadata_refresh_interval_ms, security_protocol); + + rdkafka_conf = rd_kafka_conf_new(); + rd_kafka_conf_set(rdkafka_conf, "queue.buffering.max.messages", queue_buffering_max_messages, kafka_errstr, sizeof(kafka_errstr)); + rd_kafka_conf_set(rdkafka_conf, "topic.metadata.refresh.interval.ms", topic_metadata_refresh_interval_ms, kafka_errstr, sizeof(kafka_errstr)); + rd_kafka_conf_set(rdkafka_conf, "security.protocol", security_protocol, kafka_errstr, sizeof(kafka_errstr)); + + //The conf object is freed by this function and must not be used or destroyed by the application sub-sequently. + kafka_handle = rd_kafka_new(RD_KAFKA_PRODUCER, rdkafka_conf, kafka_errstr, sizeof(kafka_errstr)); + rdkafka_conf = NULL; + if(kafka_handle == NULL){ + goto error_out; + } + return kafka_handle; + +error_out: + if(rdkafka_conf != NULL){ + rd_kafka_conf_destroy(rdkafka_conf); + rdkafka_conf = NULL; + } + if(kafka_handle != NULL){ + rd_kafka_destroy(kafka_handle); + kafka_handle = NULL; + } + return NULL; +} + +void kni_send_logger_destroy(struct kni_send_logger *handle){ + if(handle != NULL){ + if(handle->kafka_topic != NULL){ + rd_kafka_topic_destroy(handle->kafka_topic); + handle->kafka_topic = NULL; + } + if(handle->kafka_handle != NULL){ + rd_kafka_destroy(handle->kafka_handle); + handle->kafka_handle = NULL; + } + FREE(&handle); + } +} + +struct kni_send_logger* kni_send_logger_init(const char *profile, void *local_logger){ + struct kni_send_logger *handle = NULL; + const char *section = "send_logger"; + int sendlog_switch = -1; + char kafka_topic[KNI_SYMBOL_MAX] = ""; + char kafka_brokerlist[KNI_SYMBOL_MAX] = ""; + rd_kafka_t *kafka_handle = NULL; + rd_kafka_topic_t *topic = NULL; + int ret = MESA_load_profile_int_nodef(profile, section, "switch", &sendlog_switch); + if(ret < 0){ + KNI_LOG_ERROR(local_logger, "MESA_prof_load: switch not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "kafka_topic", kafka_topic, sizeof(kafka_topic)); + if(ret < 0){ + KNI_LOG_ERROR(local_logger, "MESA_prof_load: kafka_topic not set, profile is %s, section is %s", profile, section); + goto error_out; + } + ret = MESA_load_profile_string_nodef(profile, section, "kafka_brokerlist", kafka_brokerlist, sizeof(kafka_brokerlist)); + if(ret < 0){ + KNI_LOG_ERROR(local_logger, "MESA_prof_load: kafka_brokerlist not set, profile is %s, section is %s", profile, section); + goto error_out; + } + KNI_LOG_INFO(local_logger, "MESA_prof_load, [%s]:\n switch: %d\n kafka_topic: %s\n, kafka_brokerlist: %s", + section, sendlog_switch, kafka_topic, kafka_brokerlist); + handle = ALLOC(struct kni_send_logger, 1); + handle->local_logger = local_logger; + //sendlog_switch = 0, 不发送日志给kafka + if(sendlog_switch == 0){ + handle->sendlog_switch = 0; + return handle; + } + handle->sendlog_switch = 1; + //init kafka + kafka_handle = kafka_init(profile, local_logger); + if(kafka_handle == NULL){ + KNI_LOG_ERROR(local_logger, "Failed at init kafka"); + goto error_out; + } + handle->kafka_handle = kafka_handle; + //kafka_brokerlist + ret = rd_kafka_brokers_add(kafka_handle, kafka_brokerlist); + if(ret == 0){ + KNI_LOG_ERROR(local_logger, "Failed at add kafka_brokers"); + goto error_out; + } + //kafka topic + topic = rd_kafka_topic_new(kafka_handle, kafka_topic, NULL); + if(topic == NULL){ + KNI_LOG_ERROR(local_logger, "Failed at new kafka topic"); + goto error_out; + } + handle->kafka_topic = topic; + return handle; + +error_out: + kni_send_logger_destroy(handle); + return NULL; +} + +int kni_send_logger_sendlog(kni_send_logger *handle, char *log_msg, int log_msg_len){ + void *logger = handle->local_logger; + //kafka produce + int kafka_status = rd_kafka_produce(handle->kafka_topic, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY, + log_msg, log_msg_len, NULL, 0, NULL); + if(kafka_status < 0){ + KNI_LOG_ERROR(logger, "Kafka: Failed to produce, error is %s", rd_kafka_err2name(rd_kafka_last_error())); + return -1; + } + return 0; +} diff --git a/script/run.sh b/script/run.sh index 5ffb826..4a00283 100755 --- a/script/run.sh +++ b/script/run.sh @@ -1,7 +1,7 @@ SAPP_RUN="/home/tsg/kni" /bin/cp -f ../conf/sapp/conflist_business.inf $SAPP_RUN/plug/business/conflist_business.inf /bin/cp -rf ../conf/sapp/kni/ $SAPP_RUN/plug/business -/bin/cp -f ../build/entry/libkni.so $SAPP_RUN/plug/business/kni/libkni.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 diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index bc8ca1f..8d349aa 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -3,12 +3,13 @@ include(ExternalProject) -### cJSON +### cJSON: 注意: -DCMAKE_POSITION_INDEPENDENT_CODE=ON ExternalProject_Add(cJSON PREFIX cJSON URL ${CMAKE_CURRENT_SOURCE_DIR}/cJSON-1.7.7.tar.gz URL_MD5 715009c99728bf81d6c97352718650ff CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_AND_STATIC_LIBS=1) ExternalProject_Get_Property(cJSON INSTALL_DIR) @@ -20,6 +21,25 @@ set_property(TARGET cjson PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib64/libcjs set_property(TARGET cjson PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +### libUUID 注意: --enable-shared --with-pic +ExternalProject_Add(libUUID PREFIX libUUID + URL ${CMAKE_CURRENT_SOURCE_DIR}/libuuid-1.0.3.tar.gz + URL_MD5 d44d866d06286c08ba0846aba1086d68 + CONFIGURE_COMMAND cd ../libUUID && ./configure --prefix= --enable-shared --with-pic + BUILD_COMMAND cd ../libUUID && make + INSTALL_COMMAND cd ../libUUID && make install) + +ExternalProject_Get_Property(libUUID INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) + +add_library(uuid SHARED IMPORTED GLOBAL) +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) + + + + ### MESA Framework set(MESA_FRAMEWORK_LIB_DIR /opt/MESA/lib) set(MESA_FRAMEWORK_INCLUDE_DIR /opt/MESA/include) @@ -46,4 +66,8 @@ set_property(TARGET maatframe PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAM add_library(MESA_field_stat SHARED IMPORTED GLOBAL) set_property(TARGET MESA_field_stat PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_field_stat2.so) -set_property(TARGET MESA_field_stat PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) \ No newline at end of file +set_property(TARGET MESA_field_stat PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +add_library(rdkafka SHARED IMPORTED GLOBAL) +set_property(TARGET rdkafka PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/librdkafka.so) +set_property(TARGET rdkafka PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) \ No newline at end of file diff --git a/vendor/libuuid-1.0.3.tar.gz b/vendor/libuuid-1.0.3.tar.gz new file mode 100644 index 0000000..de098ad Binary files /dev/null and b/vendor/libuuid-1.0.3.tar.gz differ