#include "kni_utils.h" #include "ssl_utils.h" #include "kni_entry.h" #include "marsio.h" #include "kni_maat.h" #include "MESA/http.h" extern int g_iThreadNum; //APP_STATE_DROPME/GIVEME: 当前tcp会话的剩下包是否回调 //APP_STATE_FAWPKT/DROPPKT: 当前包是否丢弃or转发,如果是丢弃,当前包不会给后面的插件 //PROT_STATE_GIVEME/DROPME: 当前http会话的剩下包是否回调 //TODO: 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的包数,流数,收到的包数,流数 //多个tcpall插件,APP_STATE_DROPPKT, APP_STATE_FAWPKT? 有一个droppkt,就不给后面的插件了 //一个tcp流中有多个http,ssl会话的情况,只扫描第一个 struct kni_handle *g_kni_handle = NULL; struct kni_field_stat_handle *g_kni_fs_handle = NULL; //int g_http_project_id; //struct kni_marsio_handle *g_kni_marsio_handle; //g_iThreadNum 为sapp线程数 static struct pme_info* pme_info_new(){ struct pme_info* pmeinfo = ALLOC(struct pme_info, 1); return pmeinfo; } static void pme_info_destroy(struct pme_info *pmeinfo){ if(pmeinfo != NULL){ if(pmeinfo->client_tcpopt != NULL){ FREE(&(pmeinfo->client_tcpopt)); } if(pmeinfo->server_tcpopt != NULL){ FREE(&(pmeinfo->server_tcpopt)); } FREE(&pmeinfo); } } static int protocol_identify(const struct streaminfo* stream, char *buf, int len, struct protocol_identify_result *result){ //判断是http struct http_project* project = (struct http_project*)project_req_get_struct(stream, g_kni_handle->http_project_id); if(project != NULL){ result->protocol = KNI_PROTOCOL_HTTP; result->domain_len = project->host_len; memcpy(result->domain, project->host, result->domain_len); return 0; } //判断是ssl enum chello_parse_result chello_status = CHELLO_PARSE_INVALID_FORMAT; struct ssl_chello *chello = NULL; chello = ssl_chello_parse((const unsigned char*)buf, len, &chello_status); if(chello_status == CHELLO_PARSE_SUCCESS){ result->protocol = KNI_PROTOCOL_SSL; result->domain_len = strnlen(chello->sni, KNI_DOMAIN_MAX); memcpy(result->domain, chello->sni, result->domain_len); ssl_chello_free(chello); return 0; } ssl_chello_free(chello); 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; } 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; } 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); header->__magic__[0] = 0x4d; header->__magic__[1] = 0x5a; header->nr_tlvs = htons(nr_tlvs); *len = offset; return header; } static char* tcp_restore_info_header_add(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; int offset = 0; //iphdr memcpy(new_pkt, (void*)pktinfo->iphdr, pktinfo->iphdr_len); offset += pktinfo->iphdr_len; //tcphdr struct tcphdr *tcphdr = (struct tcphdr*)(new_pkt + offset); memcpy(new_pkt + offset, (void*)pktinfo->tcphdr, 20); offset += 20; tcphdr->doff = pktinfo->tcphdr->doff + 1; struct tcp_option_restore *opt = ALLOC(struct tcp_option_restore, 1); opt->kind = 88; opt->len = 4; opt->offset = htons(pktinfo->data_len); memcpy(new_pkt + offset, (void*)opt, 4); offset += 4; memcpy(new_pkt + offset, (void*)((char*)pktinfo->tcphdr + 20), pktinfo->tcphdr_len - 20); offset += pktinfo->tcphdr_len - 20; //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); memcpy(new_pkt + offset, (void*)header, header_len); offset += header_len; free(header); //iphdr: tot_len iphdr->tot_len = htons(offset); //iphdr: checksum //计算校验和之前一定要先置0 iphdr->check = 0; iphdr->check = kni_ip_checksum((void*)iphdr, pktinfo->iphdr_len); //tcphdr: checkdum tcphdr->check = 0; tcphdr->check = kni_tcp_checksum((void*)tcphdr, offset - pktinfo->iphdr_len, iphdr->saddr, iphdr->daddr); *len = offset; 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"); marsio_buff_t *tx_buffs[BURST_MAX]; unsigned int ret = 1; //TODO: marsio配置文件: 2500 int alloc_ret = marsio_buff_malloc_device(handle->dev_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); memcpy((char*)dst_data + 14, raw_data, raw_len); marsio_send_burst(handle->dev_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; FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TOT_STM], 0, FS_OP_ADD, 1); if(!pktinfo->tcphdr->syn){ //TODO: 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); 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; } pmeinfo->client_tcpopt = kni_get_tcpopt(pktinfo->tcphdr, pktinfo->tcphdr_len); 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; } static int get_action(struct ipaddr *addr, char *domain, int domain_len, int thread_seq){ //return KNI_ACTION_INTERCEPT; int action = kni_maat_scan_ip(g_kni_handle->maat_handle, addr, thread_seq, g_kni_handle->logger); if(action == KNI_ACTION_BYPASS){ return action; } action = kni_maat_scan_domain(g_kni_handle->maat_handle, domain, domain_len, thread_seq, g_kni_handle->logger); 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; 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); 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; } //TODO: client hello如果跨包怎么办?client hello后面一个包先到,这个包该丢掉还是bypass //此时 action = KNI_ACTION_UNKNOWN, 说明还没收到第一个数据包 // syn/ack包 if(pktinfo->tcphdr->syn && pktinfo->tcphdr->ack){ pmeinfo->server_tcpopt = kni_get_tcpopt(pktinfo->tcphdr, pktinfo->tcphdr_len); 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; } if(pktinfo->data_len <= 0){ 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; } //第一个数据包: 如果从第一个数据包判断不出协议,直接返回,后续包也不要了 //单向流, 直接bypass 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); 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; } struct protocol_identify_result *result = ALLOC(struct protocol_identify_result, 1); protocol_identify(stream, pktinfo->data, pktinfo->data_len, result); pmeinfo->protocol = result->protocol; if(pmeinfo->protocol == KNI_PROTOCOL_UNKNOWN){ KNI_LOG_INFO(logger, "Failed at protocol_identify, protocol is %d\n", pmeinfo->protocol); FREE(&result); 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); 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){ 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){ 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); FREE(&result); 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; } //TODO: 这块比较奇怪, 收到client hello, 但是没有syn/ack包, 直接bypass了 if(pmeinfo->client_tcpopt == NULL || pmeinfo->server_tcpopt == NULL){ KNI_LOG_ERROR(logger, "Failed at intercept, %s, %s", pmeinfo->client_tcpopt == NULL ? "no syn" : "", pmeinfo->server_tcpopt == NULL ? "no syn/ack" : ""); 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); 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); 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(){ 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; //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 //TODO: ipv6暂时不处理, ipv6: 通过nexthdr链式寻找tcp头(IPPROTO_TCP) if(stream->addr.addrtype == ADDR_TYPE_IPV6){ FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6_PKT], 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); return APP_STATE_FAWPKT | APP_STATE_DROPME; } //a_packet == NULL, 不处理这个包 if(a_packet == NULL){ FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NULL_PKT], 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); return APP_STATE_FAWPKT | APP_STATE_GIVEME; } struct pme_info *pmeinfo = *(struct pme_info **)pme; //pktinfo struct pkt_info *pktinfo = (struct pkt_info*)ALLOC(struct pkt_info, 1); pktinfo->iphdr = (struct iphdr*)a_packet; pktinfo->iphdr_len = pktinfo->iphdr->ihl * 4; pktinfo->ip_totlen = ntohs(pktinfo->iphdr->tot_len); pktinfo->tcphdr = (struct tcphdr*)((char*)pktinfo->iphdr + pktinfo->iphdr_len); pktinfo->tcphdr_len = pktinfo->tcphdr->doff * 4; pktinfo->data = (char*)pktinfo->tcphdr + pktinfo->tcphdr_len; pktinfo->data_len = pktinfo->ip_totlen - pktinfo->iphdr_len - pktinfo->tcphdr_len; int ret; switch(stream->pktstate){ case OP_STATE_PENDING: *pme = pmeinfo = pme_info_new(); 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(); break; default: ret = APP_STATE_FAWPKT | APP_STATE_GIVEME; 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_UNKNOWN_STATE_EXP], 0, FS_OP_ADD, 1); KNI_LOG_ERROR(logger, "Unknown stream opstate %d", stream->pktstate); break; } FREE(&pktinfo); if((ret & APP_STATE_DROPME)){ pme_info_destroy(pmeinfo); *pme = NULL; } return ret; } void http_project_free(int thread_seq, void *project_req_value){ FREE(&project_req_value); } static int http_project_init(){ void *logger = g_kni_handle->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); return -1; } id = project_customer_register(HTTP_PROJECT_NAME, PROJECT_VAL_TYPE_STRUCT); if(id < 0){ KNI_LOG_ERROR(logger, "Failed at project_customer_register, project name is %s, ret is %d", HTTP_PROJECT_NAME, id); return -1; } return id; } extern "C" char kni_http_entry(stSessionInfo* session_info, void **pme, int thread_seq, struct streaminfo *a_stream, const void *a_packet){ http_infor* http_info = (http_infor*)(session_info->app_info); //http_session_seq = 1表示只处理tcp链接中的第一个http会话 if(http_info->http_session_seq != 1){ return PROT_STATE_DROPME; } if(session_info->prot_flag != HTTP_HOST){ return PROT_STATE_GIVEME; } int host_len = MIN(session_info->buflen, KNI_DEFAULT_MTU); struct http_project* host_info = ALLOC(struct http_project, 1); host_info->host_len = host_len; memcpy(host_info->host, session_info->buf, host_len); if(project_req_add_struct(a_stream, g_kni_handle->http_project_id, host_info) < 0){ FREE(&host_info); host_info = NULL; } return PROT_STATE_DROPME; } static void kni_marsio_destroy(struct kni_marsio_handle *handle){ //TODO: dev_handler, dev_sendpath不需要free吗 if(handle != NULL){ if(handle->instance != NULL){ marsio_destory(handle->instance); } } FREE(&handle); } static struct kni_marsio_handle* kni_marsio_init(const char* profile){ void *logger = g_kni_handle->logger; const char* section = "marsio"; char appsym[KNI_SYMBOL_MAX]; char dev_symbol[KNI_SYMBOL_MAX]; MESA_load_profile_string_def(profile, section, "appsym", appsym, sizeof(appsym), "unknown"); MESA_load_profile_string_def(profile, section, "dev_symbol", dev_symbol, sizeof(dev_symbol), "unknown"); KNI_LOG_INFO(logger, "MESA_prof_load, [%s]:\n appsym: %s\n dev_symbol: %s", section, appsym, dev_symbol); struct mr_instance *instance = marsio_create(); if(instance == NULL){ KNI_LOG_ERROR(logger, "Failed at marsio_create"); return NULL; } unsigned int opt_value = 1; marsio_option_set(instance, 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); //设为sapp线程数 int nr_thread = g_iThreadNum; struct mr_vdev * dev_handler = marsio_open_device(instance, dev_symbol, nr_thread, nr_thread); if(dev_handler == NULL){ KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol is %s, nr_thread is %d", dev_symbol, nr_thread); return NULL; } struct mr_sendpath * dev_sendpath = marsio_sendpath_create_by_vdev(dev_handler); if(dev_sendpath == NULL){ KNI_LOG_ERROR(logger, "Failed at marsio_sendpath_create_by_vdev"); return NULL; } struct kni_marsio_handle *handle = ALLOC(struct kni_marsio_handle, 1); handle->instance = instance; handle->dev_handler = dev_handler; handle->dev_sendpath = dev_sendpath; //暂时不用调 //marsio_thread_init(mr_instance); return handle; } static struct kni_field_stat_handle * fs_init(const char *profile){ void *logger = g_kni_handle->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, "./fs2_kni.status"); 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(); if(handle == NULL){ KNI_LOG_ERROR(logger, "Failed at create FS_create_handle"); return NULL; } const char* app_name = "fs2_kni"; 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; FS_set_para(handle, FLUSH_BY_DATE, &value, sizeof(value)); value=1; FS_set_para(handle, PRINT_MODE, &value, sizeof(value)); value=1; FS_set_para(handle, CREATE_THREAD, &value, sizeof(value)); value=5; FS_set_para(handle, STAT_CYCLE, &value, sizeof(value)); 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->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"); fs_handle->fields[KNI_FIELD_INTCP_PKT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_pkt"); fs_handle->fields[KNI_FIELD_IPV6_PKT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv6_pkt"); fs_handle->fields[KNI_FIELD_NULL_PKT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "null_pkt"); fs_handle->fields[KNI_FIELD_NO_SYN_EXP] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "no_syn_pkt"); fs_handle->fields[KNI_FIELD_UNKNOWN_STATE_EXP] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "unknown_state"); fs_handle->fields[KNI_FIELD_NO_SA_EXP] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "no_s/a_pkt"); fs_handle->fields[KNI_FIELD_TOT_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tot_stm"); fs_handle->fields[KNI_FIELD_BYP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_stm"); 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_UNKNOWN_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "unknown_stm"); return fs_handle; } 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); } 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; //init http_project int id = http_project_init(); if(id < 0){ KNI_LOG_ERROR(logger, "Failed at init http project, exit. ret is %d", id); exit(EXIT_FAILURE); } 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); } //init maat g_kni_handle->maat_handle = kni_maat_init(profile, logger); if(g_kni_handle->maat_handle == NULL){ KNI_LOG_ERROR(logger, "Failed at init maat, exit"); exit(EXIT_FAILURE); } //init_filedstat struct kni_field_stat_handle *fs_handle = fs_init(profile); if(fs_handle == NULL){ KNI_LOG_ERROR(logger, "Failed at init field_stat"); } g_kni_fs_handle = fs_handle; return 0; }