This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-kni/entry/src/kni_entry.cpp

520 lines
23 KiB
C++
Raw Normal View History

2019-05-17 17:04:50 +08:00
#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流中有多个httpssl会话的情况只扫描第一个
2019-05-18 12:41:31 +08:00
struct kni_handle *g_kni_handle = NULL;
struct kni_field_stat_handle *g_kni_fs_handle = NULL;
2019-05-17 17:04:50 +08:00
//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;
2019-05-18 12:41:31 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TOT_STM], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
if(!pktinfo->tcphdr->syn){
//TODO: pending_opstate 不是syn, bypass这个流
KNI_LOG_ERROR(logger, "pending opstate: not syn");
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
pmeinfo->client_tcpopt = kni_get_tcpopt(pktinfo->tcphdr, pktinfo->tcphdr_len);
2019-05-18 12:41:31 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
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);
2019-05-18 12:41:31 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
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);
2019-05-18 12:41:31 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
if(pktinfo->data_len <= 0){
2019-05-18 12:41:31 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
//第一个数据包: 如果从第一个数据包判断不出协议,直接返回,后续包也不要了
//单向流, 直接bypass
if(stream->dir != DIR_DOUBLE){
KNI_LOG_INFO(logger, "stream dir is %d, bypass", stream->dir);
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
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);
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
//protocol = KNI_PROTOCOL_SSL/KNI_PROTOCOL_HTTP, 判断action, action返回值: KNI_ACTION_INTERCEPT/KNI_ACTION_BYPASS
2019-05-18 12:41:31 +08:00
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);
}
2019-05-17 17:04:50 +08:00
pmeinfo->action = get_action((struct ipaddr*)(&stream->addr), result->domain, result->domain_len, thread_seq);
FREE(&result);
if(pmeinfo->action == KNI_ACTION_BYPASS){
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
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" : "");
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
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);
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
return APP_STATE_DROPPKT | APP_STATE_GIVEME;
}
static char close_opstate(){
2019-05-18 12:41:31 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
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;
2019-05-18 12:41:31 +08:00
//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);
2019-05-17 17:04:50 +08:00
//当前包bypass, 剩下包bypass
//TODO: ipv6暂时不处理, ipv6: 通过nexthdr链式寻找tcp头(IPPROTO_TCP)
if(stream->addr.addrtype == ADDR_TYPE_IPV6){
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
//a_packet == NULL, 不处理这个包
if(a_packet == NULL){
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
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;
2019-05-18 12:41:31 +08:00
int ret;
2019-05-17 17:04:50 +08:00
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:
2019-05-18 12:41:31 +08:00
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);
2019-05-17 17:04:50 +08:00
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;
}
2019-05-18 12:41:31 +08:00
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;
}
2019-05-17 17:04:50 +08:00
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){
2019-05-18 12:41:31 +08:00
KNI_LOG_ERROR(logger, "Failed at init http project, exit. ret is %d", id);
2019-05-17 17:04:50 +08:00
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){
2019-05-18 12:41:31 +08:00
KNI_LOG_ERROR(logger, "Failed at init marsio, exit");
2019-05-17 17:04:50 +08:00
exit(EXIT_FAILURE);
}
//init maat
g_kni_handle->maat_handle = kni_maat_init(profile, logger);
if(g_kni_handle->maat_handle == NULL){
2019-05-18 12:41:31 +08:00
KNI_LOG_ERROR(logger, "Failed at init maat, exit");
2019-05-17 17:04:50 +08:00
exit(EXIT_FAILURE);
}
2019-05-18 12:41:31 +08:00
//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;
2019-05-17 17:04:50 +08:00
return 0;
}