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

2597 lines
109 KiB
C++
Raw Normal View History

/*
intercept: destroy_pme + send_log + del traceid2pem + del tuple2stream
bypass: drome: pme_new_fail: destroy_pme
no_tfe: destroy_pme
2019-11-15 20:48:23 +08:00
intercept_error: destroy_pme + send_log
giveme: policy: destroy_pme + send_log
dup_traffic: destroy_pme + send_log
*/
#define __STDC_FORMAT_MACROS
2019-05-17 17:04:50 +08:00
#include "kni_utils.h"
#include "marsio.h"
#include "MESA/stream_inc/sapp_inject.h"
#include "kni_cmsg.h"
#include <linux/if_ether.h>
#include <signal.h>
#include <inttypes.h>
2019-06-17 20:52:22 +08:00
#include "tfe_mgr.h"
#include <tsg/tsg_rule.h>
#include <tsg/tsg_send_log.h>
2019-11-15 20:48:23 +08:00
2019-09-11 17:52:47 +08:00
#ifdef __cplusplus
extern "C" {
#endif
#include "dablooms.h"
#ifdef __cplusplus
}
#endif
2019-09-06 16:50:37 +08:00
#include "kni_tun.h"
#include <tsg/tsg_statistic.h>
2020-05-18 14:38:14 +08:00
#include <MESA/stream_inc/stream_control.h>
#include "kni_entry.h"
#include "kni_pxy_tcp_option.h"
#include "kni_dynamic_bypass.h"
2019-05-17 17:04:50 +08:00
2020-09-23 18:10:59 +08:00
#define KNI_VAR_VERSION 20_09_v20_09_a59d3a1
#ifdef __cplusplus
extern "C"
{
#endif
#define GIT_VERSION_CATTER(v) __attribute__((__used__)) const char * GIT_VERSION_##v = NULL
#define GIT_VERSION_EXPEND(v) GIT_VERSION_CATTER(v)
/* VERSION TAG */
#ifdef KNI_VAR_VERSION
GIT_VERSION_EXPEND(KNI_VAR_VERSION);
#else
static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL;
#endif
#undef GIT_VERSION_CATTER
#undef GIT_VERSION_EXPEND
#ifdef __cplusplus
}
#endif
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;
int *arr_last_tfe_dispatch_index = NULL;
2019-11-15 20:48:23 +08:00
static char* stream_errmsg_session_record(enum intercept_error _errno){
2019-06-14 11:13:15 +08:00
switch(_errno){
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_ASYM_ROUTING:
return (char*)"e_asym_routing";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_NO_SYN:
return (char*)"e_no_syn";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_NO_SYN_ACK:
return (char*)"e_no_synack";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_INVALID_IP_HDR:
return (char*)"e_invalid_ip_hdr";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_EXCEED_MTU:
return (char*)"e_exceed_mtu";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_SENDTO_TFE_FAIL:
return (char*)"e_internal_1";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_TUPLE2STM_ADD_FAIL:
return (char*)"e_internal_2";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_NO_TFE:
return (char*)"e_internal_3";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_DUP_TRAFFIC:
return (char*)"e_internal_4";
2019-11-15 20:48:23 +08:00
case INTERCEPT_ERROR_CMSG_ADD_FAIL:
return (char*)"e_internal_5";
case INTERCEPT_ERROR_NOT_TCP_LINK_BYSYN:
return (char*)"e_internal_6";
case INTERCEPT_ERROR_GET_TCP_LINK_MODE_ERR:
return (char*)"e_internal_7";
case INTERCEPT_ERROR_STREAM_TUNNLE_TYPE:
return (char *)"e_stream_type_tunnel";
case INTERCEPT_ERROR_GET_STREAM_TUNNLE_TYPE_ERR:
return (char *)"e_internal_8";
2019-06-14 11:13:15 +08:00
default:
return (char*)"unknown error";
}
}
static int dup_traffic_dabloom_key_get(struct pkt_info *pktinfo, struct dup_traffic_dabloom_key *key){
//ipv6
struct tcphdr *tcphdr = pktinfo->tcphdr;
key->seq = tcphdr->seq;
key->ack_seq = tcphdr->ack_seq;
struct kni_tcpopt_info tcpopt;
kni_get_tcpopt(&tcpopt, tcphdr, pktinfo->tcphdr_len);
key->timestamp = tcpopt.ts_value;
if(pktinfo->addr_type == ADDR_TYPE_IPV6){
struct ip6_hdr *iphdr = pktinfo->iphdr.v6;
memcpy(key->addr.v6.saddr, &(iphdr->ip6_src), sizeof(key->addr.v6.saddr));
memcpy(key->addr.v6.daddr, &(iphdr->ip6_dst), sizeof(key->addr.v6.daddr));
key->addr.v6.source = tcphdr->source;
key->addr.v6.dest = tcphdr->dest;
}
//ipv4
else{
struct iphdr *iphdr = pktinfo->iphdr.v4;
key->addr.v4.saddr = iphdr->saddr;
key->addr.v4.daddr = iphdr->daddr;
key->addr.v4.source = tcphdr->source;
key->addr.v4.dest = tcphdr->dest;
key->ipid = iphdr->id;
}
return 0;
}
2019-06-06 17:07:17 +08:00
static void pme_info_destroy(void *data){
struct pme_info *pmeinfo = (struct pme_info *)data;
void *logger = g_kni_handle->local_logger;
if(pmeinfo != NULL){
//free lock
pthread_mutex_destroy(&(pmeinfo->lock));
//free syn/syn_ack
FREE(&(pmeinfo->syn_packet));
FREE(&(pmeinfo->syn_ack_packet));
2019-06-06 17:07:17 +08:00
FREE(&pmeinfo);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_FREE], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_CNT], 0, FS_OP_ADD, -1);
2019-06-06 17:07:17 +08:00
}
else{
KNI_LOG_ERROR(logger, "Failed at pme_info_destroy, pmeinfo = null");
2019-06-06 17:07:17 +08:00
}
}
static int pme_info_init(struct pme_info *pmeinfo, const struct streaminfo *stream, int thread_seq){
2019-06-06 17:07:17 +08:00
void *logger = g_kni_handle->local_logger;
pmeinfo->stream = stream;
2019-06-14 11:13:15 +08:00
pmeinfo->addr_type = (enum addr_type_t)stream->addr.addrtype;
pmeinfo->ssl_cert_verify = -1;
uint64_t traceid = tsg_get_stream_id((struct streaminfo*)stream);
snprintf(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid), "%" PRIu64 , traceid);
if(pmeinfo->addr_type == ADDR_TYPE_IPV6){
kni_addr_trans_v6(stream->addr.tuple4_v6, pmeinfo->stream_addr, sizeof(pmeinfo->stream_addr));
}
else{
kni_addr_trans_v4(stream->addr.tuple4_v4, pmeinfo->stream_addr, sizeof(pmeinfo->stream_addr));
}
2019-11-15 20:48:23 +08:00
//init pme_lock
int ret = pthread_mutex_init(&(pmeinfo->lock), NULL);
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at init pthread mutex, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
abort();
}
return 0;
2019-05-17 17:04:50 +08:00
}
/*keys:
common: common_has_dup_traffic, common_stream_error
http: http_host
ssl: ssl_sni, ssl_pinningst, ssl_intercept_state, ssl_server_side_latency, ssl_client_side_latency, ssl_server_side_version, ssl_client_side_version,
ssl_cert_verify
*/
static int log_generate(struct pme_info *pmeinfo){
void *local_logger = g_kni_handle->local_logger;
struct TLD_handle_t *tld_handle = pmeinfo->tld_handle;
//common
//schema_type
TLD_append(tld_handle, (char*)"common_schema_type", (void*)(pmeinfo->protocol == PROTO_SSL ? "SSL" : "HTTP"), TLD_TYPE_STRING);
//dup_traffic
TLD_append(tld_handle, (char*)"common_has_dup_traffic", (void*)pmeinfo->has_dup_traffic, TLD_TYPE_LONG);
2019-11-15 20:48:23 +08:00
//intercept_error
if(pmeinfo->intcp_error < 0){
char *stream_errmsg = stream_errmsg_session_record(pmeinfo->intcp_error);
TLD_append(tld_handle, (char*)"common_stream_error", (void*)stream_errmsg, TLD_TYPE_STRING);
}
//ssl
if(pmeinfo->protocol == PROTO_SSL){
TLD_append(tld_handle, (char*)"ssl_sni", (void*)pmeinfo->domain.sni, TLD_TYPE_STRING);
//pinning state: from tfe
TLD_append(tld_handle, (char*)"ssl_pinningst", (void*)pmeinfo->ssl_pinningst, TLD_TYPE_LONG);
//intercept state: from tfe
TLD_append(tld_handle, (char*)"ssl_intercept_state", (void*)pmeinfo->ssl_intercept_state, TLD_TYPE_LONG);
//ssl upstream latency: from tfe
TLD_append(tld_handle, (char*)"ssl_server_side_latency", (void*)pmeinfo->ssl_server_side_latency, TLD_TYPE_LONG);
//ssl downstream latency: from tfe
TLD_append(tld_handle, (char*)"ssl_client_side_latency", (void*)pmeinfo->ssl_client_side_latency, TLD_TYPE_LONG);
//ssl upstream version: from tfe
TLD_append(tld_handle, (char*)"ssl_server_side_version", (void*)pmeinfo->ssl_server_side_version, TLD_TYPE_STRING);
//ssl downstream version: from tfe
TLD_append(tld_handle, (char*)"ssl_client_side_version", (void*)pmeinfo->ssl_client_side_version, TLD_TYPE_STRING);
2020-11-03 22:06:00 +08:00
//ssl error: from tfe
if(strlen(pmeinfo->ssl_error) > 0)
TLD_append(tld_handle, (char*)"ssl_error", (void*)pmeinfo->ssl_error, TLD_TYPE_STRING);
//ssl cert verify
if(pmeinfo->ssl_cert_verify != -1){
TLD_append(tld_handle, (char*)"ssl_cert_verify", (void*)pmeinfo->ssl_cert_verify, TLD_TYPE_LONG);
}
}
//host
if(pmeinfo->protocol == PROTO_HTTP){
TLD_append(tld_handle, (char*)"http_host", (void*)pmeinfo->domain.host, TLD_TYPE_STRING);
}
tsg_log_t log_msg;
memset(&log_msg, 0, sizeof(log_msg));
log_msg.result_num = pmeinfo->maat_result_num;
log_msg.result = &(pmeinfo->maat_result);
log_msg.a_stream = NULL;
2020-09-21 13:34:29 +08:00
int ret = tsg_send_log(g_tsg_log_instance, tld_handle, &log_msg, 0);
if(ret < 0){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDLOG_FAIL], 0, FS_OP_ADD, 1);
KNI_LOG_ERROR(local_logger, "Failed at sendlog, ret = %d, strem_traceid = %s",
ret, pmeinfo->stream_traceid);
goto error_out;
}
if(pmeinfo->protocol == PROTO_SSL){
switch(pmeinfo->ssl_pinningst)
{
case 0:
tsg_set_statistic_opt(1,OPT_TYPE_PINNING_NOT, 0);
break;
case 1:
tsg_set_statistic_opt(1,OPT_TYPE_PINNING_YES, 0);
break;
case 2:
tsg_set_statistic_opt(1,OPT_TYPE_PINNING_MAYBE, 0);
break;
default:
break;
}
}
tsg_set_intercept_flow(&pmeinfo->maat_result, &pmeinfo->traffic_info,0);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SENDLOG_SUCC], 0, FS_OP_ADD, 1);
return 0;
error_out:
return -1;
}
2019-06-25 09:26:33 +06:00
static void stream_destroy(struct pme_info *pmeinfo){
2019-06-25 09:26:33 +06:00
//sendlog
2019-06-06 17:07:17 +08:00
void *logger = g_kni_handle->local_logger;
if(pmeinfo->action == KNI_ACTION_INTERCEPT){
int ret = log_generate(pmeinfo);
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at log_generate, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
}
else{
KNI_LOG_DEBUG(logger, "Succeed at log_generate, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
}
2019-06-25 09:26:33 +06:00
}
//free pme
pme_info_destroy(pmeinfo);
}
2019-06-28 09:58:54 +06:00
static int judge_stream_can_destroy(struct pme_info *pmeinfo, int caller){
2019-06-25 09:26:33 +06:00
void *logger = g_kni_handle->local_logger;
int can_destroy = 0;
2019-06-06 17:07:17 +08:00
if(pmeinfo != NULL){
pthread_mutex_lock(&(pmeinfo->lock));
if(caller == CALLER_SAPP){
pmeinfo->sapp_release = 1;
}
if(caller == CALLER_TFE){
pmeinfo->tfe_release = 1;
}
2019-06-06 17:07:17 +08:00
if(pmeinfo->sapp_release == 1 && pmeinfo->tfe_release == 1){
2019-06-25 09:26:33 +06:00
can_destroy = 1;
2019-05-17 17:04:50 +08:00
}
pthread_mutex_unlock(&(pmeinfo->lock));
2019-05-17 17:04:50 +08:00
}
2019-06-05 11:32:11 +08:00
else{
KNI_LOG_ERROR(logger, "Failed at judge_stream_can_destroy, pmeinfo = null");
2019-06-05 11:32:11 +08:00
}
2019-06-25 09:26:33 +06:00
return can_destroy;
2019-05-17 17:04:50 +08:00
}
int wrapped_kni_cmsg_set(struct kni_cmsg *cmsg, uint16_t type, const unsigned char *value, uint16_t size, struct pme_info *pmeinfo){
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 = %d/%s, stream traceid = %s, stream addr = %s", type, tfe_cmsg_tlv_type_to_string[type],pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-05-17 17:04:50 +08:00
}
else
{
KNI_LOG_DEBUG(logger, "Successd to set cmsg, type = %d/%s, stream traceid = %s, stream addr = %s", type,tfe_cmsg_tlv_type_to_string[type], pmeinfo->stream_traceid, pmeinfo->stream_addr);
}
return ret;
2019-05-17 17:04:50 +08:00
}
static int session_attribute_cmsg_set(struct kni_cmsg *cmsg, struct pme_info *pmeinfo)
{
struct _session_attribute_label_t *session_attribute_label = pmeinfo->session_attribute_label;
int ret = 0;
char empty_arr[MAX_STR_FIELD_LEN] = {0};
do {
if(session_attribute_label->client_subscribe_id == NULL)
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_SUB_ID, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
else
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_SUB_ID, (const unsigned char*)session_attribute_label->client_subscribe_id->subscribe_id, strlen(session_attribute_label->client_subscribe_id->subscribe_id), pmeinfo);
if(ret < 0) break;
if(session_attribute_label->server_subscribe_id == NULL)
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_SUB_ID, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
else
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_SUB_ID, (const unsigned char*)session_attribute_label->server_subscribe_id->subscribe_id, strlen(session_attribute_label->server_subscribe_id->subscribe_id), pmeinfo);
if(ret < 0) break;
if(session_attribute_label->client_asn == NULL)
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_ASN, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_ORGANIZATION, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
}
else
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_ASN, (const unsigned char*)session_attribute_label->client_asn->asn, strlen(session_attribute_label->client_asn->asn), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_ORGANIZATION, (const unsigned char*)session_attribute_label->client_asn->organization, strlen(session_attribute_label->client_asn->organization), pmeinfo);
if(ret < 0) break;
}
if(session_attribute_label->server_asn == NULL)
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_ASN, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_ORGANIZATION, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
}
else
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_ASN, (const unsigned char*)session_attribute_label->server_asn->asn, strlen(session_attribute_label->server_asn->asn), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_ORGANIZATION, (const unsigned char*)session_attribute_label->server_asn->organization, strlen(session_attribute_label->server_asn->organization), pmeinfo);
if(ret < 0) break;
}
if(session_attribute_label->client_location == NULL)
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_IP_LOCATION_COUNTRY, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_IP_LOCATION_PROVINE, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_IP_LOCATION_CITY, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
}
else
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_IP_LOCATION_COUNTRY, (const unsigned char*)session_attribute_label->client_location->country_full, strlen(session_attribute_label->client_location->country_full), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_IP_LOCATION_PROVINE, (const unsigned char*)session_attribute_label->client_location->province_full, strlen(session_attribute_label->client_location->province_full), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SRC_IP_LOCATION_CITY, (const unsigned char*)session_attribute_label->client_location->city_full, strlen(session_attribute_label->client_location->city_full), pmeinfo);
if(ret < 0) break;
}
if(session_attribute_label->server_location == NULL)
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_IP_LOCATION_COUNTRY, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_IP_LOCATION_PROVINE, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_IP_LOCATION_CITY, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
if(ret < 0) break;
}
else
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_IP_LOCATION_COUNTRY, (const unsigned char*)session_attribute_label->server_location->country_full, strlen(session_attribute_label->server_location->country_full), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_IP_LOCATION_PROVINE, (const unsigned char*)session_attribute_label->server_location->province_full, strlen(session_attribute_label->server_location->province_full), pmeinfo);
if(ret < 0) break;
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_DST_IP_LOCATION_CITY, (const unsigned char*)session_attribute_label->server_location->city_full, strlen(session_attribute_label->server_location->city_full), pmeinfo);
if(ret < 0) break;
}
if(session_attribute_label->ja3_fingerprint == NULL)
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
else
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT, (const unsigned char*)session_attribute_label->ja3_fingerprint, strlen(session_attribute_label->ja3_fingerprint), pmeinfo);
2020-09-29 17:47:13 +08:00
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_FQDN_CAT_ID_NUM, (const unsigned char*)&(session_attribute_label->fqdn_category_id_num), sizeof(unsigned int), pmeinfo);
2020-09-29 17:47:13 +08:00
if(session_attribute_label->fqdn_category_id_num <= 0 || session_attribute_label->fqdn_category_id_num > 8)
{
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_FQDN_CAT_ID_VAL, (const unsigned char*)empty_arr, strlen(empty_arr), pmeinfo);
2020-09-29 17:47:13 +08:00
}
else
{
char fqdn_val[sizeof(session_attribute_label->fqdn_category_id)] = {0};
for(int i = 0 ; i < session_attribute_label->fqdn_category_id_num; i ++)
{
memcpy((void *)(fqdn_val + i * (sizeof(unsigned int))), (void *)&(session_attribute_label->fqdn_category_id[i]), sizeof(unsigned int));
}
ret = wrapped_kni_cmsg_set(cmsg,TFE_CMSG_FQDN_CAT_ID_VAL, (const unsigned char*)fqdn_val,session_attribute_label->fqdn_category_id_num *sizeof(unsigned int) , pmeinfo);
2020-09-29 17:47:13 +08:00
}
}while(0);
return ret;
}
static unsigned int get_stream_common_direction(struct streaminfo *stream)
{
int i_or_e=0;
unsigned int direction=0;
i_or_e=MESA_dir_link_to_human(stream->routedir);
switch(stream->curdir)
{
case DIR_C2S:
if(i_or_e=='E' || i_or_e=='e')
{
direction='E';
}
else
{
direction='I';
}
break;
case DIR_S2C:
if(i_or_e=='E' || i_or_e=='e')
{
direction='I';
}
else
{
direction='E';
}
break;
default:
break;
}
return direction;
}
2019-09-18 15:56:59 +08:00
static unsigned char* kni_cmsg_serialize_header_new(struct pme_info *pmeinfo, struct streaminfo *stream, 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 == PROTO_SSL ? 0x1 : 0x0;
uint8_t protocol_type = 0x0;
struct kni_cmsg *cmsg = kni_cmsg_init();
char *trace_id = NULL;
uint32_t seq = pktinfo->tcphdr->seq;
uint32_t ack = pktinfo->tcphdr->ack_seq;
if(g_kni_handle->pxy_tcp_option_enable == 1){
pxy_tcp_option_modify_mss(pmeinfo, logger);
}
uint16_t client_mss = htons(pmeinfo->client_tcpopt.mss);
uint16_t server_mss = htons(pmeinfo->server_tcpopt.mss);
2019-06-05 15:42:46 +08:00
uint16_t client_window = htons(pmeinfo->client_window);
uint16_t server_window = htons(pmeinfo->server_window);
unsigned char stream_curdir = stream->curdir;
if(stream_curdir == DIR_S2C)
{
seq = pktinfo->tcphdr->ack_seq;
ack = pktinfo->tcphdr->seq;
}
2019-12-02 16:52:30 +08:00
char src_mac[6] = {0};
char dst_mac[6] = {0};
int policy_id;
unsigned int stream_common_direction;
switch(pmeinfo->protocol)
{
case PROTO_SSL:
protocol_type = 0x1;
break;
case PROTO_SSH:
protocol_type = 0x2;
break;
default:
protocol_type = 0x0;
}
//seq
int ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_SEQ, (const unsigned char*)&seq, 4, pmeinfo);
if(ret < 0) goto error_out;
//ack
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_ACK, (const unsigned char*)&ack, 4, pmeinfo);
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, pmeinfo);
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, pmeinfo);
if(ret < 0) goto error_out;
//both = 1, send to tfe
if(pmeinfo->client_tcpopt.wscale_set && pmeinfo->server_tcpopt.wscale_set){
//client wscale
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, (const unsigned char*)&(pmeinfo->client_tcpopt.wscale), 1, pmeinfo);
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, pmeinfo);
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, pmeinfo);
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, pmeinfo);
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_set), 1, pmeinfo);
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_set), 1, pmeinfo);
if(ret < 0) goto error_out;
//client timestamp val
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL, (const unsigned char*)&(pmeinfo->client_tcpopt.ts_value), 4, pmeinfo);
if(ret < 0) goto error_out;
//server timestamp val
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL, (const unsigned char*)&(pmeinfo->server_tcpopt.ts_value), 4, pmeinfo);
if(ret < 0) goto error_out;
//protocol
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (const unsigned char*)&protocol_type, 1, pmeinfo);
if(ret < 0) goto error_out;
2019-06-05 15:42:46 +08:00
//client window
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT, (const unsigned char*)&client_window, 2, pmeinfo);
2019-06-05 15:42:46 +08:00
if(ret < 0) goto error_out;
//server window
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_WINDOW_SERVER, (const unsigned char*)&server_window, 2, pmeinfo);
2019-06-05 15:42:46 +08:00
if(ret < 0) goto error_out;
//current packet direction
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR, (const unsigned char*)&stream_curdir, 1, pmeinfo);
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), pmeinfo);
if(ret < 0) goto error_out;
//stream trace id
trace_id = pmeinfo->stream_traceid;
2019-06-05 11:32:11 +08:00
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_STREAM_TRACE_ID, (const unsigned char*)trace_id,
strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid)), pmeinfo);
if(ret < 0) goto error_out;
// proxy tcp option
if(g_kni_handle->pxy_tcp_option_enable == 1)
{
ret = pxy_tcp_option_cmsg_set(cmsg, pmeinfo);
if(ret < 0)
{
KNI_LOG_DEBUG(logger, "Proxy-tcp-option: Failed at set cmsg");
goto error_out;
}
}
//share session attribute
ret = session_attribute_cmsg_set(cmsg, pmeinfo);
if(ret < 0)
{
KNI_LOG_ERROR(logger, "share-session-attribute: Failed at set cmsg");
goto error_out;
}
//common direction
stream_common_direction = get_stream_common_direction(stream);
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_COMMON_DIRECTION, (const unsigned char*)&stream_common_direction, sizeof(stream_common_direction), pmeinfo);
if(ret < 0) goto error_out;
2019-09-18 15:56:59 +08:00
//src mac
ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC, src_mac);
2019-09-18 15:56:59 +08:00
if(ret < 0){
2019-12-02 16:52:30 +08:00
KNI_LOG_DEBUG(logger, "Failed at get src mac from rawpkt, ret = %d, maybe two-arm mode", ret);
2019-09-18 15:56:59 +08:00
}
KNI_LOG_DEBUG(logger, "Succeed at get src mac from rawpkt, addr = %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5]);
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_SRC_MAC, (const unsigned char*)src_mac, sizeof(src_mac), pmeinfo);
2019-09-18 15:56:59 +08:00
if(ret < 0) goto error_out;
//dst mac
ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC, dst_mac);
2019-09-18 15:56:59 +08:00
if(ret < 0){
2019-12-02 16:52:30 +08:00
KNI_LOG_DEBUG(logger, "Failed at get dst mac from rawpkt, ret = %d, maybe two-arm mode", ret);
2019-09-18 15:56:59 +08:00
}
KNI_LOG_DEBUG(logger, "Succeed at get dst mac from rawpkt, addr = %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]);
ret = wrapped_kni_cmsg_set(cmsg, TFE_CMSG_DST_MAC, (const unsigned char*)dst_mac, sizeof(dst_mac), pmeinfo);
2019-09-18 15:56:59 +08:00
if(ret < 0) goto error_out;
bufflen = kni_cmsg_serialize_size_get(cmsg);
KNI_LOG_DEBUG(logger, "Successd set cmsg size:%d, stream traceid = %s", bufflen, pmeinfo->stream_traceid);
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 = %d, stream traceid = %s, stream addr = %s",
ret, pmeinfo->stream_traceid, pmeinfo->stream_addr);
goto error_out;
}
*len = serialize_len;
kni_cmsg_destroy(cmsg);
return buff;
error_out:
if(buff != NULL){
FREE(&buff);
}
kni_cmsg_destroy(cmsg);
return NULL;
2019-05-17 17:04:50 +08:00
}
2019-09-18 15:56:59 +08:00
static char* add_cmsg_to_packet(struct pme_info *pmeinfo, struct streaminfo *stream, struct pkt_info *pktinfo, int *len){
2019-05-17 17:04:50 +08:00
//tcp option: kind 88, len 4, control_info_len
void * logger = g_kni_handle->local_logger;
2019-05-17 17:04:50 +08:00
char *new_pkt = (char*)ALLOC(struct wrapped_packet, 1);
int offset = 0;
//iphdr
KNI_LOG_DEBUG(logger, "Kni add cmsg to packet malloc buffer size:%d",sizeof(struct wrapped_packet));
2019-06-14 11:13:15 +08:00
if(pmeinfo->addr_type == ADDR_TYPE_IPV6){
memcpy(new_pkt, (void*)pktinfo->iphdr.v6, pktinfo->iphdr_len);
}
else{
memcpy(new_pkt, (void*)pktinfo->iphdr.v4, pktinfo->iphdr_len);
}
2019-05-17 17:04:50 +08:00
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);
FREE(&opt);
2019-05-17 17:04:50 +08:00
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;
//kni_cmsg_serialize_header
uint16_t header_len = 0;
2019-09-18 15:56:59 +08:00
unsigned char* header = kni_cmsg_serialize_header_new(pmeinfo, stream, pktinfo, &header_len);
if(header == NULL){
KNI_LOG_ERROR(logger, "Kni add cmsg to packet: serialize_header failed");
goto error_out;
}
2019-05-17 17:04:50 +08:00
memcpy(new_pkt + offset, (void*)header, header_len);
offset += header_len;
KNI_LOG_DEBUG(logger, "Kni add cmsg to packet:offset=%d,header_len=%d, tcp_data_len=%d",offset,header_len,pktinfo->data_len);
FREE(&header);
2019-06-14 11:13:15 +08:00
//ipv6
if(pmeinfo->addr_type == ADDR_TYPE_IPV6){
kni_ipv6_header_parse((void*)new_pkt, pktinfo);
pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(offset - sizeof(ip6_hdr));
pktinfo->tcphdr->check = 0;
pktinfo->tcphdr->check = kni_tcp_checksum_v6((void*)pktinfo->tcphdr,
offset - pktinfo->iphdr_len, pktinfo->iphdr.v6->ip6_src, pktinfo->iphdr.v6->ip6_dst);
}
else{
struct iphdr *iphdr = (struct iphdr*)new_pkt;
iphdr->tot_len = htons(offset);
//must set check = 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);
}
2019-05-17 17:04:50 +08:00
*len = offset;
return new_pkt;
error_out:
if(new_pkt != NULL){
FREE(&new_pkt);
}
return NULL;
2019-05-17 17:04:50 +08:00
}
2019-09-06 16:50:37 +08:00
static int add_ether_header(void *dst_data, void *raw_data, uint16_t raw_len, addr_type_t addr_type){
char *src_mac = g_kni_handle->src_mac_addr;
char *dst_mac = g_kni_handle->dst_mac_addr;
//ether_header[14]
struct ethhdr *ether_hdr = (struct ethhdr*)dst_data;
memcpy(ether_hdr->h_dest, dst_mac, sizeof(ether_hdr->h_dest));
memcpy(ether_hdr->h_source, src_mac, sizeof(ether_hdr->h_source));
if(addr_type == ADDR_TYPE_IPV6){
ether_hdr->h_proto = htons(ETH_P_IPV6);
}
else{
ether_hdr->h_proto = htons(ETH_P_IP);
}
memcpy((char*)dst_data + sizeof(*ether_hdr), raw_data, raw_len);
return 0;
}
2019-08-19 17:23:15 +08:00
static int send_to_tfe_normal_mode(char *raw_data, uint16_t raw_len, int thread_seq, int tfe_id, addr_type_t addr_type){
void *logger = g_kni_handle->local_logger;
2019-08-19 17:23:15 +08:00
struct kni_marsio_handle *handle = g_kni_handle->marsio_handle;
2019-05-17 17:04:50 +08:00
marsio_buff_t *tx_buffs[BURST_MAX];
int index = -1;
for(int i = 0; i < handle->tfe_enabled_node_count; i++){
if(handle->tfe_enabled_nodes[i].tfe_id == tfe_id){
index = i;
break;
}
}
if(index == -1){
KNI_LOG_ERROR(logger, "tfd %d = disabled");
return -1;
}
struct mr_vdev *dev_eth_handler = handle->tfe_enabled_nodes[index].dev_eth_handler;
struct mr_sendpath *dev_eth_sendpath = handle->tfe_enabled_nodes[index].dev_eth_sendpath;
2019-06-09 20:00:44 +08:00
//only send one packet, alloc_ret <= nr_send <= BURST_MAX
int nr_send = 1;
int alloc_ret = marsio_buff_malloc_device(dev_eth_handler, tx_buffs, nr_send, 0, thread_seq);
2019-05-17 17:04:50 +08:00
if (alloc_ret < 0){
KNI_LOG_ERROR(logger, "Failed at alloc marsio buffer, ret = %d, thread_seq = %d",
alloc_ret, thread_seq);
2019-05-17 17:04:50 +08:00
return -1;
}
for(int i = 0; i < nr_send; i++){
2019-09-06 16:50:37 +08:00
char* dst_data = marsio_buff_append(tx_buffs[i], raw_len + sizeof(struct ethhdr));
add_ether_header(dst_data, raw_data, raw_len, addr_type);
}
marsio_send_burst(dev_eth_sendpath, thread_seq, tx_buffs, nr_send);
2019-05-17 17:04:50 +08:00
return 0;
}
2019-09-06 16:50:37 +08:00
static int send_to_tfe_tun_mode(char *raw_data, uint16_t raw_len, addr_type_t addr_type){
struct kni_tun_handle *handle = g_kni_handle->tun_handle;
char *dst_data = ALLOC(char, KNI_MTU);
add_ether_header(dst_data, raw_data, raw_len, addr_type);
int ret = kni_tun_write(handle, dst_data, raw_len + sizeof(struct ethhdr));
FREE(&dst_data);
2019-08-19 17:23:15 +08:00
if(ret < 0){
return -1;
}
return 0;
2019-08-07 15:42:55 +08:00
}
2019-08-19 17:23:15 +08:00
static int send_to_tfe(char *raw_data, uint16_t raw_len, int thread_seq, int tfe_id, addr_type_t addr_type){
2019-09-06 16:50:37 +08:00
int mode = g_kni_handle->deploy_mode;
2019-08-07 15:42:55 +08:00
int ret;
2019-09-06 16:50:37 +08:00
if(mode == KNI_DEPLOY_MODE_TUN){
ret = send_to_tfe_tun_mode(raw_data, raw_len, addr_type);
2019-08-07 15:42:55 +08:00
}
else{
2019-09-06 16:50:37 +08:00
ret = send_to_tfe_normal_mode(raw_data, raw_len, thread_seq, tfe_id, addr_type);
2019-08-07 15:42:55 +08:00
}
return ret;
}
2019-11-15 20:48:23 +08:00
static void wrapped_kni_header_parse(const void *a_packet, struct pme_info *pmeinfo, struct pkt_info *pktinfo){
void *logger = g_kni_handle->local_logger;
2019-06-14 11:13:15 +08:00
if(pmeinfo->addr_type == ADDR_TYPE_IPV6){
int ret = kni_ipv6_header_parse(a_packet, pktinfo);
if(ret < 0){
char *errmsg = kni_ipv6_errmsg_get((enum kni_ipv6hdr_parse_error)ret);
KNI_LOG_ERROR(logger, "Failed at parse ipv6 header, errmsg = %s, stream treaceid = %s",
2019-06-14 11:13:15 +08:00
errmsg, pmeinfo->stream_traceid);
2019-11-15 20:48:23 +08:00
pktinfo->parse_failed = 1;
2019-06-14 11:13:15 +08:00
}
}
else{
int ret = kni_ipv4_header_parse(a_packet, pktinfo);
if(ret < 0){
char *errmsg = kni_ipv4_errmsg_get((enum kni_ipv4hdr_parse_error)ret);
KNI_LOG_ERROR(logger, "Failed at parse ipv4 header, errmsg = %s, stream treaceid = %s",
2019-06-14 11:13:15 +08:00
errmsg, pmeinfo->stream_traceid);
2019-11-15 20:48:23 +08:00
pktinfo->parse_failed = 1;
2019-06-14 11:13:15 +08:00
}
}
2019-11-15 20:48:23 +08:00
return;
2019-06-14 11:13:15 +08:00
}
static int tuple2stream_htable_key_get_v4_by_packet(struct pkt_info *pktinfo, struct stream_tuple4_v4 *key, int *reversed){
if(pktinfo->iphdr.v4->saddr < pktinfo->iphdr.v4->daddr){
key->saddr = pktinfo->iphdr.v4->saddr;
key->daddr = pktinfo->iphdr.v4->daddr;
key->source = pktinfo->tcphdr->source;
key->dest = pktinfo->tcphdr->dest;
*reversed = 0;
}
else{
key->saddr = pktinfo->iphdr.v4->daddr;
key->daddr = pktinfo->iphdr.v4->saddr;
key->source = pktinfo->tcphdr->dest;
key->dest = pktinfo->tcphdr->source;
*reversed = 1;
}
return 0;
}
static int tuple2stream_htable_key_get_v6_by_packet(struct pkt_info *pktinfo, struct stream_tuple4_v6 *key, int *reversed){
if(memcmp((void*)&(pktinfo->iphdr.v6->ip6_src), (void*)&(pktinfo->iphdr.v6->ip6_dst), sizeof(key->saddr)) < 0){
memcpy(key->saddr, &(pktinfo->iphdr.v6->ip6_src), sizeof(key->saddr));
memcpy(key->daddr, &(pktinfo->iphdr.v6->ip6_dst), sizeof(key->daddr));
key->source = pktinfo->tcphdr->source;
key->dest = pktinfo->tcphdr->dest;
*reversed = 0;
}
else{
memcpy(key->saddr, &(pktinfo->iphdr.v6->ip6_dst), sizeof(key->saddr));
memcpy(key->daddr, &(pktinfo->iphdr.v6->ip6_src), sizeof(key->daddr));
key->source = pktinfo->tcphdr->dest;
key->dest = pktinfo->tcphdr->source;
*reversed = 1;
}
return 0;
}
static int tuple2stream_htable_key_get_v4_by_stream(const struct streaminfo *stream, struct stream_tuple4_v4 *key, int *reversed){
if(stream->addr.tuple4_v4->saddr < stream->addr.tuple4_v4->daddr){
key->saddr = stream->addr.tuple4_v4->saddr;
key->daddr = stream->addr.tuple4_v4->daddr;
key->source = stream->addr.tuple4_v4->source;
key->dest = stream->addr.tuple4_v4->dest;
*reversed = 0;
}
else{
key->saddr = stream->addr.tuple4_v4->daddr;
key->daddr = stream->addr.tuple4_v4->saddr;
key->source = stream->addr.tuple4_v4->dest;
key->dest = stream->addr.tuple4_v4->source;
*reversed = 1;
}
return 0;
}
static int tuple2stream_htable_key_get_v6_by_stream(const struct streaminfo *stream, struct stream_tuple4_v6 *key, int *reversed){
if(memcmp(stream->addr.tuple4_v6->saddr, stream->addr.tuple4_v6->daddr, sizeof(key->saddr)) < 0){
memcpy(key->saddr, stream->addr.tuple4_v6->saddr, sizeof(key->saddr));
memcpy(key->daddr, stream->addr.tuple4_v6->daddr, sizeof(key->daddr));
key->source = stream->addr.tuple4_v6->source;
key->dest = stream->addr.tuple4_v6->dest;
*reversed = 0;
}
else{
memcpy(key->saddr, stream->addr.tuple4_v6->daddr, sizeof(key->saddr));
memcpy(key->daddr, stream->addr.tuple4_v6->saddr, sizeof(key->daddr));
key->source = stream->addr.tuple4_v6->dest;
key->dest = stream->addr.tuple4_v6->source;
*reversed = 1;
}
return 0;
}
static int tuple2stream_htable_add(addr_type_t addr_type, struct pkt_info *pktinfo,
struct streaminfo *stream, struct pme_info *pmeinfo, int thread_seq){
MESA_htable_handle tuple2stream_htable = g_kni_handle->threads_handle[thread_seq].tuple2stream_htable;
void *logger = g_kni_handle->local_logger;
int ret;
char key_str[KNI_ADDR_MAX];
struct tuple2stream_htable_value *value = ALLOC(struct tuple2stream_htable_value, 1);
value->stream = stream;
value->pmeinfo = pmeinfo;
value->route_dir = stream->routedir;
//ipv6
if(addr_type == ADDR_TYPE_IPV6){
struct stream_tuple4_v6 key;
tuple2stream_htable_key_get_v6_by_packet(pktinfo, &key, &(value->reversed));
ret = MESA_htable_add(tuple2stream_htable, (const unsigned char *)&key, sizeof(key), (const void*)value);
if(ret < 0){
kni_addr_trans_v6(&key, key_str, sizeof(key_str));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1);
KNI_LOG_ERROR(logger, "MESA_htable: Failed at add, table = tuple2stream_htable, key = %s, key_size = %d, ret = %d",
key_str, sizeof(key), ret);
}
}
//ipv4
else{
struct stream_tuple4_v4 key;
tuple2stream_htable_key_get_v4_by_packet(pktinfo, &key, &(value->reversed));
ret = MESA_htable_add(tuple2stream_htable, (const unsigned char *)&key, sizeof(key), (const void*)value);
if(ret < 0){
kni_addr_trans_v4(&key, key_str, sizeof(key_str));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1);
KNI_LOG_ERROR(logger, "MESA_htable: Failed at add, table = tuple2stream_htable, key = %s, key_size = %d, ret = %d",
key_str, sizeof(key), ret);
}
}
if(ret >= 0){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_SUCC], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[1], g_kni_fs_handle->column_ids[thread_seq], FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[1], g_kni_fs_handle->column_ids[g_kni_handle->thread_count], FS_OP_ADD, 1);
}
return ret;
}
static int traceid2pme_htable_add(struct pme_info *pmeinfo){
2019-06-14 11:13:15 +08:00
void *logger = g_kni_handle->local_logger;
2019-11-15 20:48:23 +08:00
int key_size = 0, ret;
key_size = strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid));
ret = MESA_htable_add(g_kni_handle->traceid2pme_htable, (const unsigned char *)(pmeinfo->stream_traceid),
key_size, (const void*)pmeinfo);
2019-06-14 11:13:15 +08:00
if(ret < 0){
KNI_LOG_ERROR(logger, "MESA_htable: Failed at add,"
"table = traceid2pme_htable, key = %s, ret = %d", pmeinfo->stream_traceid, ret);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_ADD_FAIL], 0, FS_OP_ADD, 1);
2019-06-14 11:13:15 +08:00
}
else{
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_ADD_SUCC], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_CNT], 0, FS_OP_ADD, 1);
2019-06-14 11:13:15 +08:00
}
return ret;
}
int tuple2stream_htable_del(const struct streaminfo *stream, int thread_seq){
MESA_htable_handle handle = g_kni_handle->threads_handle[thread_seq].tuple2stream_htable;
void *logger = g_kni_handle->local_logger;
int reversed = 0, ret = -1;
char key_str[KNI_ADDR_MAX];
//ipv6
if(stream->addr.addrtype == ADDR_TYPE_IPV6){
struct stream_tuple4_v6 key;
tuple2stream_htable_key_get_v6_by_stream(stream, &key, &reversed);
ret = MESA_htable_del(handle, (const unsigned char *)(&key),
sizeof(key), NULL);
if(ret < 0){
kni_addr_trans_v6(&key, key_str, sizeof(key_str));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_FAIL], 0, FS_OP_ADD, 1);
KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table = %s, key = %s, key_size = %d, ret = %d",
"tuple2stream_htable", key_str, sizeof(key), ret);
}
2019-06-14 11:13:15 +08:00
}
//ipv4
2019-06-14 11:13:15 +08:00
else{
struct stream_tuple4_v4 key;
tuple2stream_htable_key_get_v4_by_stream(stream, &key, &reversed);
ret = MESA_htable_del(handle, (const unsigned char *)(&key), sizeof(key), NULL);
if(ret < 0){
kni_addr_trans_v4(&key, key_str, sizeof(key_str));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_FAIL], 0, FS_OP_ADD, 1);
KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table = %s, key = %s, key_size = %d, ret = %d",
"tuple2stream_htable", key_str, sizeof(key), ret);
}
}
if(ret >= 0){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_SUCC], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[1], g_kni_fs_handle->column_ids[thread_seq], FS_OP_ADD, -1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[1], g_kni_fs_handle->column_ids[g_kni_handle->thread_count], FS_OP_ADD, -1);
2019-06-14 11:13:15 +08:00
}
return ret;
}
static void traceid2pme_htable_del(struct pme_info *pmeinfo){
//del traceid2pme htable
if(pmeinfo->action == KNI_ACTION_INTERCEPT){
void *logger = g_kni_handle->local_logger;
int key_size = strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid));
int ret;
ret = MESA_htable_del(g_kni_handle->traceid2pme_htable, (const unsigned char *)pmeinfo->stream_traceid,
key_size, NULL);
if(ret < 0){
KNI_LOG_ERROR(logger, "MESA_htable: Failed at del, table = %s, key = %s, key_size = %d, ret = %d",
"traceid2pme_htable", pmeinfo->stream_traceid, key_size, ret);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_FAIL], 0, FS_OP_ADD, 1);
}
else{
//KNI_LOG_DEBUG(logger, "MESA_htable: Succeed at del, table = %s, key = %s, key_size = %d",
// "traceid2pme_htable", pmeinfo->stream_traceid, key_size);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_CNT], 0, FS_OP_ADD, -1);
}
}
}
static int dabloom_add(struct pkt_info *pktinfo, int thread_seq){
void *logger = g_kni_handle->local_logger;
struct dup_traffic_dabloom_key bloom_key;
memset(&bloom_key, 0, sizeof(bloom_key));
dup_traffic_dabloom_key_get(pktinfo, &bloom_key);
int ret = expiry_dablooms_add(g_kni_handle->threads_handle[thread_seq].dabloom_handle, (const char*)&bloom_key, sizeof(bloom_key));
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at expiry_dablooms_add, errmsg = %s", expiry_dablooms_errno_trans((enum expiry_dablooms_errno)ret));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_ADD_FAIL], 0, FS_OP_ADD, 1);
}
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_ADD_SUCC], 0, FS_OP_ADD, 1);
uint64_t count = 0;
expiry_dablooms_element_count_get(g_kni_handle->threads_handle[thread_seq].dabloom_handle, &count);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[0], g_kni_fs_handle->column_ids[thread_seq], FS_OP_SET, count);
return ret;
}
static struct _session_attribute_label_t * kni_pull_session_attribute_results(struct streaminfo *a_stream,struct pme_info *pmeinfo)
{
struct _session_attribute_label_t *session_attribute_label = NULL;
void *logger = g_kni_handle->local_logger;
session_attribute_label = (struct _session_attribute_label_t *)project_req_get_struct(a_stream, g_kni_handle->session_attribute_id);
if(session_attribute_label != NULL)
{
KNI_LOG_DEBUG(logger, "share-session-attribute: Success to get the session attribute results,stream traceid = %s", pmeinfo->stream_traceid);
if(session_attribute_label->client_subscribe_id == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: source subscribe id is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
KNI_LOG_DEBUG(logger, "share-session-attribute: source subscribe id is: %s,stream traceid = %s",session_attribute_label->client_subscribe_id->subscribe_id,pmeinfo->stream_traceid);
if(session_attribute_label->server_subscribe_id == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: destination subscribe id is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
KNI_LOG_DEBUG(logger, "share-session-attribute: destination subscribe id is: %s,stream traceid = %s",session_attribute_label->server_subscribe_id->subscribe_id,pmeinfo->stream_traceid);
if(session_attribute_label->client_asn == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: source asn and organization is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
{
KNI_LOG_DEBUG(logger, "share-session-attribute: source asn is: %s,stream traceid = %s",session_attribute_label->client_asn->asn, pmeinfo->stream_traceid);
KNI_LOG_DEBUG(logger, "share-session-attribute: source organization is: %s,stream traceid = %s",session_attribute_label->client_asn->organization, pmeinfo->stream_traceid);
}
if(session_attribute_label->server_asn == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: destination asn and organization is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
{
KNI_LOG_DEBUG(logger, "share-session-attribute: destination asn:%s,stream traceid = %s",session_attribute_label->server_asn->asn,pmeinfo->stream_traceid);
KNI_LOG_DEBUG(logger, "share-session-attribute: destination organization:%s,stream traceid = %s",session_attribute_label->server_asn->organization,pmeinfo->stream_traceid);
}
if(session_attribute_label->client_location == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: source ip location is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
{
KNI_LOG_DEBUG(logger, "share-session-attribute: source ip location country is: %s,stream traceid = %s",session_attribute_label->client_location->country_full,pmeinfo->stream_traceid);
KNI_LOG_DEBUG(logger, "share-session-attribute: source ip location province is: %s,stream traceid = %s",session_attribute_label->client_location->province_full,pmeinfo->stream_traceid);
KNI_LOG_DEBUG(logger, "share-session-attribute: source ip location city is: %s,stream traceid = %s",session_attribute_label->client_location->city_full,pmeinfo->stream_traceid);
}
if(session_attribute_label->server_location == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: destination ip location is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
{
KNI_LOG_DEBUG(logger, "share-session-attribute: destination ip location country is: %s,stream traceid = %s",session_attribute_label->server_location->country_full,pmeinfo->stream_traceid);
KNI_LOG_DEBUG(logger, "share-session-attribute: destination ip location province is: %s,stream traceid = %s",session_attribute_label->server_location->province_full,pmeinfo->stream_traceid);
KNI_LOG_DEBUG(logger, "share-session-attribute: destination ip location city is: %s,stream traceid = %s",session_attribute_label->server_location->city_full,pmeinfo->stream_traceid);
}
if(session_attribute_label->ja3_fingerprint == NULL)
KNI_LOG_DEBUG(logger, "share-session-attribute: ja3_fingerprint is NULL,stream traceid = %s",pmeinfo->stream_traceid);
else
KNI_LOG_DEBUG(logger, "share-session-attribute: ja3_fingerprint is %s,stream traceid = %s",session_attribute_label->ja3_fingerprint,pmeinfo->stream_traceid);
2020-09-29 17:47:13 +08:00
if(session_attribute_label->fqdn_category_id_num < 0 || session_attribute_label->fqdn_category_id_num > 8)
{
KNI_LOG_DEBUG(logger, "share-session-attribute: fqdn_category_id_num out of range( 0 <= value <= 8), value = %d,stream traceid = %s",session_attribute_label->fqdn_category_id_num,pmeinfo->stream_traceid);
}
else
{
for(int i= 0; i < session_attribute_label->fqdn_category_id_num; i ++)
{
KNI_LOG_DEBUG(logger, "share-session-attribute: fqdn_category_id[%d] = %u,stream traceid = %s",i,session_attribute_label->fqdn_category_id[i],pmeinfo->stream_traceid);
2020-09-29 17:47:13 +08:00
}
}
}
else
{
KNI_LOG_ERROR(logger, "share-session-attribute: Failed to get the session attribute results,stream traceid = %s", pmeinfo->stream_traceid);
}
return session_attribute_label;
}
static int tsg_diagnose_judge_streamshunt(int maat_rule_config_id,struct pme_info *pmeinfo)
{
int i = 0 ,ret = 0;
void *logger = g_kni_handle->local_logger;
if(g_kni_handle->tsg_diagnose_enable == 0){
KNI_LOG_DEBUG(logger, "Tsg diagnose: enabled is 0, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
return 0;
}
if(g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_num == 0){
KNI_LOG_DEBUG(logger, "Tsg diagnose: no security policy from profile to shunt, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
return 0;
}
for(i = 0; i < g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_num; i ++){
if(g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_arr[i] == 0){
KNI_LOG_DEBUG(logger, "Tsg diagnose: security policy 0 is not allowd shunt, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
continue;
}
if(g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_arr[i] == maat_rule_config_id){
ret = 1;
KNI_LOG_DEBUG(logger, "Tsg diagnose: security policy id %d shunt, stream traceid = %s, stream addr = %s", maat_rule_config_id, pmeinfo->stream_traceid, pmeinfo->stream_addr);
break;
}
}
return ret;
}
2019-11-15 20:48:23 +08:00
static int first_data_intercept(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, int thread_seq){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_READY_STM], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_READY_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen);
void *logger = g_kni_handle->local_logger;
char *buff = NULL;
int ret, len;
//intercept_error: TCP CTEAT LINK NOT BYSYN or TCP_CREATE_LINK_MODE error
unsigned char intercept_stream_link_mode;
int intercept_stream_link_mode_len = sizeof(unsigned char);
unsigned short stream_tunnel_type = STREAM_TUNNLE_NON;
int stream_tunnel_type_len = sizeof(unsigned short);
ret=MESA_get_stream_opt(stream, MSO_TCP_CREATE_LINK_MODE, (void *)&intercept_stream_link_mode, &intercept_stream_link_mode_len);
if(ret == 0){
if(intercept_stream_link_mode != TCP_CTEAT_LINK_BYSYN){
KNI_LOG_DEBUG(logger, "Intercept error: TCP_CREATE_LINK_MODE is not BYSYN, link_mode=%d, link_mode_len=%d,stream traceid = %s, stream addr = %s", intercept_stream_link_mode,intercept_stream_link_mode_len,pmeinfo->stream_traceid, pmeinfo->stream_addr);
pmeinfo->intcp_error = INTERCEPT_ERROR_NOT_TCP_LINK_BYSYN;
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_NOT_LINK_MODE_BYSYN], 0, FS_OP_ADD, 1);
goto error_out;
}
}
else{
KNI_LOG_DEBUG(logger, "Intercept error: get MSO_TCP_CREATE_LINK_MODE error, ret = %d, stream traceid = %s, stream addr = %s",ret, pmeinfo->stream_traceid, pmeinfo->stream_addr);
pmeinfo->intcp_error = INTERCEPT_ERROR_GET_TCP_LINK_MODE_ERR;
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_GET_LINK_MODE_ERR], 0, FS_OP_ADD, 1);
goto error_out;
}
ret=MESA_get_stream_opt(stream, MSO_STREAM_TUNNEL_TYPE, (void *)&stream_tunnel_type, &stream_tunnel_type_len);
if(ret == 0){
if(stream_tunnel_type != STREAM_TUNNLE_NON){
KNI_LOG_DEBUG(logger, "Intercept error: stream type is tunnel, STREAM_TUNNLE_TYPE = %d, stream traceid = %s, stream addr = %s", stream_tunnel_type,pmeinfo->stream_traceid, pmeinfo->stream_addr);
pmeinfo->intcp_error = INTERCEPT_ERROR_STREAM_TUNNLE_TYPE;
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_STREAM_IS_TUN_TYPE], 0, FS_OP_ADD, 1);
goto error_out;
}
}
else
{
KNI_LOG_DEBUG(logger, "Intercept error: get MSO_STREAM_TUNNEL_TYPE error, ret = %d, stream traceid = %s, stream addr = %s",ret, pmeinfo->stream_traceid, pmeinfo->stream_addr);
pmeinfo->intcp_error = INTERCEPT_ERROR_GET_STREAM_TUNNLE_TYPE_ERR;
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_GET_STREAM_TUN_TYPE_ERR], 0, FS_OP_ADD, 1);
goto error_out;
}
2021-04-21 19:50:44 +08:00
2019-11-15 20:48:23 +08:00
//intercept_error: not double dir
if(stream->dir != DIR_DOUBLE){
KNI_LOG_DEBUG(logger, "Intercept error: asym routing, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_ASYM_ROUTING], 0, FS_OP_ADD, 1);
pmeinfo->intcp_error = INTERCEPT_ERROR_ASYM_ROUTING;
goto error_out;
}
//intercept_error: no syn
if(pmeinfo->has_syn == 0){
KNI_LOG_DEBUG(logger, "Intercept error: no syn, stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_NO_SYN], 0, FS_OP_ADD, 1);
pmeinfo->intcp_error = INTERCEPT_ERROR_NO_SYN;
goto error_out;
}
//intercept_error: no syn/ack
if(pmeinfo->has_syn_ack == 0){
KNI_LOG_DEBUG(logger, "Intercept error: no syn/ack, stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_NO_SYN_ACK], 0, FS_OP_ADD, 1);
pmeinfo->intcp_error = INTERCEPT_ERROR_NO_SYN_ACK;
goto error_out;
}
if(pktinfo->parse_failed == 1){
pmeinfo->intcp_error = INTERCEPT_ERROR_INVALID_IP_HDR;
KNI_LOG_DEBUG(logger, "Intercept error: invalid ip header, stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-11-15 20:48:23 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_INVALID_IP_HDR], 0, FS_OP_ADD, 1);
goto error_out;
}
//intercept_error: first data > 1500, bypass and dropme
if(pktinfo->ip_totlen > KNI_DEFAULT_MTU){
pmeinfo->intcp_error = INTERCEPT_ERROR_EXCEED_MTU;
KNI_LOG_DEBUG(logger, "Intercept error: first data packet exceed MTU(1500), stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_EXCEED_MTU], 0, FS_OP_ADD, 1);
goto error_out;
}
2021-04-21 19:50:44 +08:00
//intercept_error: no tfe
if(tsg_diagnose_judge_streamshunt(pmeinfo->maat_result.config_id,pmeinfo) == 0) // tsg diagnose shunt
pmeinfo->tfe_id = tfe_mgr_alive_node_get(g_kni_handle->_tfe_mgr, thread_seq);
else
pmeinfo->tfe_id = tfe_mgr_alive_node_cycle_get(g_kni_handle->_tfe_mgr, (int *)&(g_kni_handle->arr_last_tfe_dispatch_index[thread_seq]));
if(pmeinfo->tfe_id < 0){
KNI_LOG_DEBUG(logger, "Intercept error: no available tfe, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
pmeinfo->intcp_error = INTERCEPT_ERROR_NO_TFE;
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_NO_TFE], 0, FS_OP_ADD, 1);
goto error_out;
}
//dup_traffic_check
if(g_kni_handle->dup_traffic_switch == 1){
//has dup traffic
if(pmeinfo->has_dup_syn == 1 || pmeinfo->has_dup_syn_ack == 1){
pmeinfo->has_dup_traffic = 1;
}
if(pmeinfo->has_dup_traffic == 1){
if(g_kni_handle->dup_traffic_action == KNI_ACTION_BYPASS){
2019-11-15 20:48:23 +08:00
KNI_LOG_DEBUG(g_kni_handle->local_logger, "Intercept error: stream has dup traffic, dup_traffic_action = bypass, "
"stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-11-15 20:48:23 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_DUP_TRAFFIC], 0, FS_OP_ADD, 1);
pmeinfo->intcp_error = INTERCEPT_ERROR_DUP_TRAFFIC;
goto error_out;
}
}
}
//Bypass Duplicated Packet
if(g_kni_handle->pxy_tcp_option_enable == 1)
{
if(pmeinfo->has_dup_traffic == 1 && pmeinfo->pxy_tcp_option.bypass_duplicated_packet == 1)
{
KNI_LOG_DEBUG(g_kni_handle->local_logger, "Proxy-tcp-option: bypass Duplicated Packet first data, streamid = %d", pmeinfo->stream_traceid);
2020-09-29 17:47:13 +08:00
return APP_STATE_FAWPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
}
}
//
if(pmeinfo->session_attribute_label == NULL)
{
KNI_LOG_DEBUG(g_kni_handle->local_logger, "Intercept error: Get share session attribute error,stream traceid = %s", pmeinfo->stream_traceid);
goto error_out;
}
//dynamic bypass
if(g_kni_handle->ssl_dynamic_bypass_enable == 1){
if(first_data_ssl_dynamic_bypass(stream, pmeinfo, pktinfo, thread_seq) == 0)
{
//dynamic bypass fs stat
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DY_PASS_STM], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DY_PASS_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen);
//dynamic bypass ipv4 or ipv6
if(stream->addr.addrtype == ADDR_TYPE_IPV6){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DY_PASS_IPV6_STM], 0, FS_OP_ADD, 1);
}
else{
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DY_PASS_IPV4_STM], 0, FS_OP_ADD, 1);
}
if(pmeinfo->has_dup_traffic == 1){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DUP_TFC_STM], 0, FS_OP_ADD, 1);
KNI_LOG_DEBUG(logger, "stream has dup traffic, traceid = %s", pmeinfo->stream_traceid);
}
pmeinfo->ssl_intercept_state = 0;
pmeinfo->is_dynamic_bypass = 1;
if(g_kni_handle->dup_traffic_switch == 1){
if(pmeinfo->has_dup_traffic == 1){
ret = dabloom_add(pktinfo, thread_seq);
if(ret < 0){
KNI_LOG_DEBUG(logger, "stream add dabloom fail, ret=%d, traceid = %s",ret, pmeinfo->stream_traceid);
}
}
}
2020-09-29 17:47:13 +08:00
return APP_STATE_FAWPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
}
}
2019-11-15 20:48:23 +08:00
//add cmsg
len = 0;
buff = add_cmsg_to_packet(pmeinfo, stream, pktinfo, &len);
if(buff == NULL){
KNI_LOG_DEBUG(logger, "Intercept error: failed at add cmsg to packet, stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
pmeinfo->intcp_error = INTERCEPT_ERROR_CMSG_ADD_FAIL;
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_CMSG_ADD_FAIL], 0, FS_OP_ADD, 1);
goto error_out;
}
//add to tuple2stream_htable
ret = tuple2stream_htable_add(pmeinfo->addr_type, pktinfo, stream, pmeinfo, thread_seq);
2019-06-14 11:13:15 +08:00
if(ret < 0){
2019-11-15 20:48:23 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1);
KNI_LOG_DEBUG(logger, "Intercept error: tuple2stm add fail, stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-11-15 20:48:23 +08:00
pmeinfo->intcp_error = INTERCEPT_ERROR_TUPLE2STM_ADD_FAIL;
goto error_out;
2019-06-14 11:13:15 +08:00
}
2019-11-15 20:48:23 +08:00
//Note: traceid2pme_add_fail, still work. no cmsg
traceid2pme_htable_add(pmeinfo);
//send to tfe
2019-08-19 17:23:15 +08:00
ret = send_to_tfe(buff, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type);
2019-06-14 11:13:15 +08:00
if(ret < 0){
2019-11-15 20:48:23 +08:00
KNI_LOG_DEBUG(logger, "Intercept error: failed at send first packet to tfe%d, stream traceid = %s, stream addr = %s",
pmeinfo->tfe_id, pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-11-15 20:48:23 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1);
pmeinfo->intcp_error = INTERCEPT_ERROR_SENDTO_TFE_FAIL;
tuple2stream_htable_del(stream, thread_seq);
traceid2pme_htable_del(pmeinfo);
2019-11-15 20:48:23 +08:00
goto error_out;
2019-06-14 11:13:15 +08:00
}
else{
KNI_LOG_DEBUG(logger, "Succeed at send first packet to tfe%d, stream traceid = %s, stream addr = %s",
pmeinfo->tfe_id, pmeinfo->stream_traceid, pmeinfo->stream_addr);
}
//fs stat
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_STM], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen);
//ipv4 or ipv6
if(stream->addr.addrtype == ADDR_TYPE_IPV6){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6_STM], 0, FS_OP_ADD, 1);
}
else{
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV4_STM], 0, FS_OP_ADD, 1);
}
//http or ssl
2019-11-15 20:48:23 +08:00
if(pmeinfo->protocol == PROTO_SSL){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SSL_STM], 0, FS_OP_ADD, 1);
}
2019-11-15 20:48:23 +08:00
if(pmeinfo->protocol == PROTO_HTTP){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_HTTP_STM], 0, FS_OP_ADD, 1);
}
//dup_traffic_stm
if(pmeinfo->has_dup_traffic == 1){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DUP_TFC_STM], 0, FS_OP_ADD, 1);
KNI_LOG_DEBUG(logger, "stream has dup traffic, traceid = %s", pmeinfo->stream_traceid);
}
2019-11-15 20:48:23 +08:00
FREE(&buff);
2020-09-29 17:47:13 +08:00
return APP_STATE_DROPPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
2019-11-15 20:48:23 +08:00
error_out:
if(buff != NULL){
FREE(&buff);
}
2020-09-29 17:47:13 +08:00
return APP_STATE_FAWPKT | APP_STATE_KILL_FOLLOW | APP_STATE_DROPME;
2019-06-14 11:13:15 +08:00
}
static int dabloom_search(struct pkt_info *pktinfo, int thread_seq){
void *logger = g_kni_handle->local_logger;
struct dup_traffic_dabloom_key bloom_key;
memset(&bloom_key, 0, sizeof(bloom_key));
dup_traffic_dabloom_key_get(pktinfo, &bloom_key);
int ret = expiry_dablooms_search(g_kni_handle->threads_handle[thread_seq].dabloom_handle, (const char*)&bloom_key, sizeof(bloom_key));
//ret = 1, = dup packet, bypass the packet
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at expiry_dablooms_search, errmsg = %s", expiry_dablooms_errno_trans((enum expiry_dablooms_errno)ret));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_FAIL], 0, FS_OP_ADD, 1);
}
2019-09-11 17:52:47 +08:00
else{
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_SUCC], 0, FS_OP_ADD, 1);
2019-09-11 17:52:47 +08:00
if(ret == 1){
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_HIT], 0, FS_OP_ADD, 1);
2019-09-17 17:24:22 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_DUP_TFC_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen);
2019-09-11 17:52:47 +08:00
}
else{
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BLOOM_MISS], 0, FS_OP_ADD, 1);
}
}
uint64_t count = 0;
expiry_dablooms_element_count_get(g_kni_handle->threads_handle[thread_seq].dabloom_handle, &count);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->line_ids[0], g_kni_fs_handle->column_ids[thread_seq], FS_OP_SET, count);
return ret;
}
2019-11-15 20:48:23 +08:00
/* action
0x00: none
0x02: intercept
0x80: bypass
*/
char* kni_maat_action_trans(enum kni_action action){
switch(action){
case 0x00:
return (char*)"none";
case 0x02:
return (char*)"intercept";
case 0x80:
return (char*)"bypass";
default:
return (char*)"unknown";
}
}
char next_data_intercept(struct pme_info *pmeinfo, const void *a_packet, struct pkt_info *pktinfo, int thread_seq){
2019-11-15 20:48:23 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_READY_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen);
int ret, len;
void *logger = g_kni_handle->local_logger;
2019-06-14 11:13:15 +08:00
struct iphdr *ipv4_hdr = NULL;
2019-11-15 20:48:23 +08:00
struct ip6_hdr* ipv6_hdr = NULL;
if(pktinfo->parse_failed == 1){
2020-01-15 17:24:12 +08:00
KNI_LOG_ERROR(logger, "next_data_intercept: invalid ip header, drop pkt and not send to tfe");
2020-09-29 17:47:13 +08:00
return APP_STATE_DROPPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
2019-11-15 20:48:23 +08:00
}
//search dabloom
if(g_kni_handle->dup_traffic_switch == 1){
if(pmeinfo->has_dup_traffic == 1){
//ret = 1, = dup packet, bypass the packet
if(g_kni_handle->pxy_tcp_option_enable == 1)
{
if(pmeinfo->pxy_tcp_option.bypass_duplicated_packet == 1){ //Bypass Duplicated Packet
2020-09-29 17:47:13 +08:00
return APP_STATE_FAWPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
}
}
2019-11-15 20:48:23 +08:00
ret = dabloom_search(pktinfo, thread_seq);
if(ret == 1){
2020-09-29 17:47:13 +08:00
return APP_STATE_FAWPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
2019-11-15 20:48:23 +08:00
}
}
}
if(pmeinfo->addr_type == ADDR_TYPE_IPV6){
2019-11-15 20:48:23 +08:00
ipv6_hdr = (struct ip6_hdr*)a_packet;
len = ntohs(ipv6_hdr->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr);
}
else{
2019-11-15 20:48:23 +08:00
ipv4_hdr = (struct iphdr*)a_packet;
len = ntohs(ipv4_hdr->tot_len);
}
2019-12-16 10:59:35 +08:00
if(pktinfo->ip_totlen > KNI_DEFAULT_MTU){
2019-11-15 20:48:23 +08:00
KNI_LOG_DEBUG(logger, "Next data packet exceed MTU(1500), stream traceid = %s, stream addr = %s",
pmeinfo->stream_traceid, pmeinfo->stream_addr);
2020-09-29 17:47:13 +08:00
return APP_STATE_DROPPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
2019-09-16 16:45:25 +08:00
}
if(g_kni_handle->ssl_dynamic_bypass_enable == 1){
if(pmeinfo->is_dynamic_bypass){
next_data_ssl_dynamic_bypass(pktinfo);
2020-09-29 17:47:13 +08:00
return APP_STATE_FAWPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
}
}
2019-11-15 20:48:23 +08:00
ret = send_to_tfe((char*)a_packet, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type);
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at send continue packet to tfe%d, stream traceid = %s, stream addr = %s",
pmeinfo->tfe_id, pmeinfo->stream_traceid, pmeinfo->stream_addr);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCPERR_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1);
}
2019-11-15 20:48:23 +08:00
else{
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen);
2019-05-17 17:04:50 +08:00
}
2020-09-29 17:47:13 +08:00
return APP_STATE_DROPPKT | APP_STATE_KILL_FOLLOW | APP_STATE_GIVEME;
2019-11-15 20:48:23 +08:00
}
char first_data_process(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, int thread_seq){
//first data packet, get action
void *logger = g_kni_handle->local_logger;
int maat_hit = 0;
int ret = 0;
struct identify_info _identify_info;
ret = tsg_pull_policy_result(stream, PULL_KNI_RESULT, &(pmeinfo->maat_result), 1, &_identify_info);
2019-11-15 20:48:23 +08:00
//ret == 0, bypass and dropme
if(ret == 0){
pmeinfo->action = KNI_ACTION_NONE;
maat_hit = 0;
KNI_LOG_INFO(logger, "intercept_policy_scan: %s, %s, maat_hit = %d, stream traceid = %s",
pmeinfo->stream_addr, (char*)&(pmeinfo->domain), maat_hit, pmeinfo->stream_traceid);
2019-05-17 17:04:50 +08:00
}
2019-11-15 20:48:23 +08:00
else{
pmeinfo->maat_result_num = 1;
pmeinfo->protocol = _identify_info.proto;
pmeinfo->domain_len = MIN(_identify_info.domain_len, (int)sizeof(pmeinfo->domain) - 1);
strncpy(pmeinfo->domain.sni, _identify_info.domain, pmeinfo->domain_len);
pmeinfo->action = (enum kni_action)(pmeinfo->maat_result.action);
pmeinfo->policy_id = pmeinfo->maat_result.config_id;
pmeinfo->do_log = pmeinfo->maat_result.do_log;
pmeinfo->thread_seq = thread_seq;
pmeinfo->is_dynamic_bypass = 0;
pmeinfo->session_attribute_label = kni_pull_session_attribute_results(stream,pmeinfo);
2019-11-15 20:48:23 +08:00
maat_hit = 1;
char *action_str = kni_maat_action_trans(pmeinfo->action);
KNI_LOG_INFO(logger, "intercept_policy_scan: %s, %s, maat_hit = %d, policy_id = %d, action = %d(%s), stream traceid = %s",
pmeinfo->stream_addr, (char*)&(pmeinfo->domain), maat_hit, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->stream_traceid);
2019-05-18 12:41:31 +08:00
}
2019-06-04 13:25:44 +08:00
switch(pmeinfo->action){
case KNI_ACTION_INTERCEPT:
pmeinfo->ssl_intercept_state = 1;
//only action = intercept, need sendlog
pmeinfo->tld_handle = TLD_create(-1);
if(g_kni_handle->pxy_tcp_option_enable == 1)
{
KNI_LOG_DEBUG(logger, "Proxy-tcp-option: before scan status:%d ( 1 is has been scanned, other value not scan),stream traceid = %s", pmeinfo->pxy_tcp_option_is_scan,pmeinfo->stream_traceid);
if(pmeinfo->pxy_tcp_option_is_scan != 1)
{
pxy_tcp_option_get_param(g_tsg_maat_feather,(const struct streaminfo *)stream,pmeinfo,logger);
pmeinfo->pxy_tcp_option_is_scan = 1;
}
}
2019-11-15 20:48:23 +08:00
return first_data_intercept(stream, pmeinfo, pktinfo, thread_seq);
2019-06-04 13:25:44 +08:00
default:
2019-11-15 20:48:23 +08:00
//action != interceptbypass and dropme
2019-06-04 13:25:44 +08:00
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
2019-05-17 17:04:50 +08:00
}
2020-01-15 17:24:12 +08:00
void dup_traffic_detect(struct pme_info *pmeinfo, struct pkt_info *pktinfo){
if(g_kni_handle->dup_traffic_switch == 0){
return;
}
//syn
if(pktinfo->tcphdr->syn && !pktinfo->tcphdr->ack){
if(pmeinfo->syn_packet == NULL){
struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1);
dup_traffic_dabloom_key_get(pktinfo, syn_packet);
pmeinfo->syn_packet = syn_packet;
}
else{
struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1);
dup_traffic_dabloom_key_get(pktinfo, syn_packet);
if(memcmp(pmeinfo->syn_packet, syn_packet, sizeof(*syn_packet)) == 0){
pmeinfo->has_dup_syn = 1;
}
FREE(&(pmeinfo->syn_packet));
pmeinfo->syn_packet = syn_packet;
}
}
//syn/ack
if(pktinfo->tcphdr->syn && pktinfo->tcphdr->ack){
if(pmeinfo->syn_ack_packet == NULL){
struct dup_traffic_dabloom_key *syn_ack_packet = ALLOC(struct dup_traffic_dabloom_key, 1);
dup_traffic_dabloom_key_get(pktinfo, syn_ack_packet);
pmeinfo->syn_ack_packet = syn_ack_packet;
}
else{
struct dup_traffic_dabloom_key *syn_ack_packet = ALLOC(struct dup_traffic_dabloom_key, 1);
dup_traffic_dabloom_key_get(pktinfo, syn_ack_packet);
if(memcmp(pmeinfo->syn_ack_packet, syn_ack_packet, sizeof(*syn_ack_packet)) == 0){
pmeinfo->has_dup_syn_ack = 1;
}
FREE(&(pmeinfo->syn_ack_packet));
pmeinfo->syn_ack_packet = syn_ack_packet;
}
}
}
void tcp_handshake_pkt_process(struct pme_info *pmeinfo, struct pkt_info *pktinfo){
//syn
if(pktinfo->tcphdr->syn && !pktinfo->tcphdr->ack){
pmeinfo->client_window = ntohs(pktinfo->tcphdr->window);
pmeinfo->has_syn = 1;
kni_get_tcpopt(&(pmeinfo->client_tcpopt), pktinfo->tcphdr, pktinfo->tcphdr_len);
}
//syn/ack
if(pktinfo->tcphdr->syn && pktinfo->tcphdr->ack){
pmeinfo->server_window = ntohs(pktinfo->tcphdr->window);
pmeinfo->has_syn_ack = 1;
kni_get_tcpopt(&(pmeinfo->server_tcpopt), pktinfo->tcphdr, pktinfo->tcphdr_len);
}
dup_traffic_detect(pmeinfo, pktinfo);
}
2019-11-15 20:48:23 +08:00
static char data_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){
2020-01-15 17:24:12 +08:00
void *logger = g_kni_handle->local_logger;
2019-11-15 20:48:23 +08:00
//parse ipv4/6 header
struct pkt_info pktinfo;
memset(&pktinfo, 0, sizeof(pktinfo));
2019-11-15 20:48:23 +08:00
wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo);
//pmeinfo->action has only 2 value: KNI_ACTION_NONE, KNI_ACTION_INTERCEPT
if(pmeinfo->action == KNI_ACTION_INTERCEPT){
return next_data_intercept(pmeinfo, a_packet, &pktinfo, thread_seq);
2019-11-15 20:48:23 +08:00
}
//first data
if(stream->ptcpdetail->datalen > 0){
return first_data_process(stream, pmeinfo, &pktinfo, thread_seq);
}
2020-01-15 17:24:12 +08:00
//before first data, may be dup_syn, syn/ack, dup_syn/ack
if(pktinfo.parse_failed != 0){
KNI_LOG_ERROR(logger, "before first data: invalid ip header, bypass pkt");
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
2019-11-15 20:48:23 +08:00
}
2020-01-15 17:24:12 +08:00
tcp_handshake_pkt_process(pmeinfo, &pktinfo);
2019-11-15 20:48:23 +08:00
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
static int kni_set_policy_into_pem_info(const struct streaminfo *a_stream, struct pme_info *pmeinfo)
{
struct _traffic_info *traffic_info = &(pmeinfo->traffic_info);
int value_len=sizeof(unsigned long long);
if(a_stream == NULL || pmeinfo == NULL)
return -1;
traffic_info->con_num = 1;
MESA_get_stream_opt(a_stream, MSO_TOTAL_INBOUND_BYTE_RAW, (void *)&traffic_info->in_bytes, &value_len);
MESA_get_stream_opt(a_stream, MSO_TOTAL_INBOUND_PKT, (void *)&traffic_info->in_packets, &value_len);
MESA_get_stream_opt(a_stream, MSO_TOTAL_OUTBOUND_BYTE_RAW, (void *)&traffic_info->out_bytes, &value_len);
MESA_get_stream_opt(a_stream, MSO_TOTAL_OUTBOUND_PKT, (void *)&traffic_info->out_packets, &value_len);
return 0;
}
2019-06-14 11:13:15 +08:00
static char close_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, int thread_seq){
2019-11-27 18:00:19 +08:00
//close: because of timeout, return value has no meaning
2019-06-04 13:25:44 +08:00
switch(pmeinfo->action){
case KNI_ACTION_INTERCEPT:
TLD_append_streaminfo(g_tsg_log_instance, pmeinfo->tld_handle, (struct streaminfo*)pmeinfo->stream);
kni_set_policy_into_pem_info(stream,pmeinfo);
2019-06-05 11:32:11 +08:00
//reset clock: when sapp end, start clock
if(pmeinfo->is_dynamic_bypass != 1)
{
MESA_htable_search(g_kni_handle->traceid2pme_htable, (const unsigned char*)pmeinfo->stream_traceid,
strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid)));
tuple2stream_htable_del(stream, thread_seq);
}
2019-11-27 18:00:19 +08:00
return APP_STATE_FAWPKT | APP_STATE_DROPME;
2019-11-15 20:48:23 +08:00
//stream has no data.
2019-06-06 17:07:17 +08:00
default:
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
2019-05-17 17:04:50 +08:00
}
2019-11-15 20:48:23 +08:00
static void pending_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){
2020-01-15 17:24:12 +08:00
void *logger = g_kni_handle->local_logger;
2019-11-15 20:48:23 +08:00
pme_info_init(pmeinfo, stream, thread_seq);
struct pkt_info pktinfo;
wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo);
if(pktinfo.parse_failed == 1){
2020-01-15 17:24:12 +08:00
KNI_LOG_ERROR(logger, "pending opstate: invalid ip header, bypass pkt");
2019-11-15 20:48:23 +08:00
return;
}
2020-01-15 17:24:12 +08:00
tcp_handshake_pkt_process(pmeinfo, &pktinfo);
2019-11-15 20:48:23 +08:00
return;
}
2019-06-04 19:50:34 +08:00
//from syn
extern "C" char kni_tcpall_entry(struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){
void *logger = g_kni_handle->local_logger;
int ret;
2019-06-25 09:26:33 +06:00
int can_destroy;
2019-06-06 17:07:17 +08:00
struct pme_info *pmeinfo = *(struct pme_info **)pme;
2019-06-14 11:13:15 +08:00
/* a_packet == NULL && not op_state_close, continue
close: a_packet may be null, if a_packet = null, do not send to tfe
*/
if(a_packet == NULL && stream->pktstate != OP_STATE_CLOSE){
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NULL_PKT], 0, FS_OP_ADD, 1);
2019-05-17 17:04:50 +08:00
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
2020-01-15 17:24:12 +08:00
enum addr_type_t addr_type = (enum addr_type_t)stream->addr.addrtype;
if(addr_type != ADDR_TYPE_IPV6 && addr_type != ADDR_TYPE_IPV4){
KNI_LOG_ERROR(logger, "addr_type(%d) is not ipv4 or ipv6, bypass stream");
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
2020-10-19 19:15:56 +08:00
2019-05-17 17:04:50 +08:00
switch(stream->pktstate){
case OP_STATE_PENDING:
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STATE_PENDING], 0, FS_OP_ADD, 1);
pmeinfo = ALLOC(struct pme_info, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_NEW_SUCC], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_PME_CNT], 0, FS_OP_ADD, 1);
*pme = pmeinfo;
2019-11-15 20:48:23 +08:00
pending_opstate(stream, pmeinfo, a_packet, thread_seq);
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME;
2019-05-17 17:04:50 +08:00
break;
case OP_STATE_DATA:
2019-06-14 11:13:15 +08:00
ret = data_opstate(stream, pmeinfo, a_packet, thread_seq);
2019-05-17 17:04:50 +08:00
break;
case OP_STATE_CLOSE:
2019-06-06 17:07:17 +08:00
//sapp stream close
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STATE_CLOSE], 0, FS_OP_ADD, 1);
2019-06-14 11:13:15 +08:00
ret = close_opstate(stream, pmeinfo, thread_seq);
2019-05-17 17:04:50 +08:00
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_STATE_UNKNOWN], 0, FS_OP_ADD, 1);
KNI_LOG_ERROR(logger, "Unknown stream opstate %d, stream traceid = %s, stream addr = %s",
stream->pktstate, pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-05-17 17:04:50 +08:00
break;
}
//sapp release: bypass or intercept
2019-11-15 20:48:23 +08:00
/* dropme has 3 status:
0. not intercept: action != KNI_ACTION_INTERCEPT
1. intercept failed: action = KNI_ACTION_INTERCEPT, intercept_error < 0
2. intercept succeed, normal closed: action = KNI_ACTION_INTERCEPT, intercept_error = 0
*/
2019-05-17 17:04:50 +08:00
if((ret & APP_STATE_DROPME)){
2019-11-15 20:48:23 +08:00
if(pmeinfo->action != KNI_ACTION_INTERCEPT){
if(pmeinfo != NULL){
stream_destroy(pmeinfo);
2019-11-15 20:48:23 +08:00
}
}
else{
if(pmeinfo->intcp_error < 0){
pmeinfo->ssl_intercept_state = 0;
2019-11-15 20:48:23 +08:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_INTCPERR], 0, FS_OP_ADD, 1);
if(pmeinfo != NULL){
//pmeinfo->policy_id = -1;
TLD_append_streaminfo(g_tsg_log_instance, pmeinfo->tld_handle, (struct streaminfo*)pmeinfo->stream);
stream_destroy(pmeinfo);
2019-11-15 20:48:23 +08:00
}
}
else{
if(pmeinfo->is_dynamic_bypass == 0) // stream is dynamic bypass 0: not dynamic bypass 1: dynamic bypass
{
can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_SAPP);
if(can_destroy == 1){
traceid2pme_htable_del(pmeinfo);
stream_destroy(pmeinfo);
}
2019-11-15 20:48:23 +08:00
}
else
{
stream_destroy(pmeinfo);
}
}
2019-06-25 09:26:33 +06:00
}
2019-06-06 17:07:17 +08:00
}
return ret;
2019-05-17 17:04:50 +08:00
}
static void kni_marsio_destroy(struct kni_marsio_handle *handle){
if(handle != NULL){
if(handle->instance != NULL){
marsio_destory(handle->instance);
}
}
FREE(&handle);
handle = NULL;
2019-05-17 17:04:50 +08:00
}
2019-06-09 20:00:44 +08:00
int tuple2stream_htable_search(MESA_htable_handle handle, struct ethhdr *ether_hdr, int thread_seq){
2019-06-09 20:00:44 +08:00
void *logger = g_kni_handle->local_logger;
if(ether_hdr->h_proto != htons(ETH_P_IP) && ether_hdr->h_proto != htons(ETH_P_IPV6)){
return -1;
2019-06-09 20:00:44 +08:00
}
void *raw_packet = (char*)ether_hdr + sizeof(*ether_hdr);
tuple2stream_htable_value *value = NULL;
struct pkt_info pktinfo;
int reversed = 0, ret;
int key_size = 0;
char key_str[KNI_ADDR_MAX];
struct stream_tuple4_v6 key_v6;
struct stream_tuple4_v4 key_v4;
memset(key_str,0,sizeof(key_str));
2019-06-14 11:13:15 +08:00
//ipv6
if(ether_hdr->h_proto == htons(ETH_P_IPV6)){
ret = kni_ipv6_header_parse(raw_packet, &pktinfo);
2019-06-14 11:13:15 +08:00
if(ret < 0){
char *errmsg = kni_ipv6_errmsg_get((enum kni_ipv6hdr_parse_error)ret);
KNI_LOG_ERROR(logger, "failed at parse ipv6 header, errmsg = %s", errmsg);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL], 0, FS_OP_ADD, 1);
return -1;
2019-06-14 11:13:15 +08:00
}
tuple2stream_htable_key_get_v6_by_packet(&pktinfo, &key_v6, &reversed);
value = (tuple2stream_htable_value*)MESA_htable_search(handle, (const unsigned char*)(&key_v6), sizeof(key_v6));
2019-06-14 11:13:15 +08:00
}
//ipv4
else{
ret = kni_ipv4_header_parse(raw_packet, &pktinfo);
if(ret < 0){
char *errmsg = kni_ipv4_errmsg_get((enum kni_ipv4hdr_parse_error)ret);
KNI_LOG_ERROR(logger, "failed at parse ipv4 header, errmsg = %s", errmsg);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV4HDR_PARSE_FAIL], 0, FS_OP_ADD, 1);
return -1;
}
tuple2stream_htable_key_get_v4_by_packet(&pktinfo, &key_v4, &reversed);
value = (tuple2stream_htable_value*)MESA_htable_search(handle, (const unsigned char*)(&key_v4), sizeof(key_v4));
}
if(value == NULL){
if(ether_hdr->h_proto == htons(ETH_P_IPV6)){
kni_addr_trans_v6(&key_v6, key_str, sizeof(key_str));
}
else{
kni_addr_trans_v4(&key_v4, key_str, sizeof(key_str));
}
KNI_LOG_DEBUG(logger, "MESA_htable: search not hit, table is tuple2stream_htable, key = %s, key_size = %d", key_str, strlen(key_str));
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_MISS], 0, FS_OP_ADD, 1);
return -1;
}
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_HIT], 0, FS_OP_ADD, 1);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_SUCC], 0, FS_OP_ADD, 1);
2019-09-07 20:21:50 +08:00
unsigned char dir = value->route_dir;
if(reversed != value->reversed){
dir = MESA_dir_reverse(dir);
}
2019-09-07 20:21:50 +08:00
ret = sapp_inject_pkt(value->stream, SIO_EXCLUDE_THIS_LAYER_HDR, raw_packet, pktinfo.ip_totlen, dir);
2019-06-09 20:00:44 +08:00
if(ret < 0){
if(ether_hdr->h_proto == htons(ETH_P_IPV6)){
kni_addr_trans_v6(&key_v6, key_str, sizeof(key_str));
}
else{
kni_addr_trans_v4(&key_v4, key_str, sizeof(key_str));
}
KNI_LOG_ERROR(logger, "Failed at sapp_inject_pkt, stream addr = %s", key_str);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SAPP_INJECT_FAIL], 0, FS_OP_ADD, 1);
return -1;
2019-06-09 20:00:44 +08:00
}
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_SAPP_INJECT_SUCC], 0, FS_OP_ADD, 1);
//add to dabloom
if(g_kni_handle->dup_traffic_switch == 1){
if(value->pmeinfo->has_dup_traffic == 1){
ret = dabloom_add(&pktinfo, thread_seq);
if(ret < 0){
return -1;
}
}
}
return 0;
}
extern "C" char kni_polling_all_entry(const struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){
2019-09-06 16:50:37 +08:00
void *logger = g_kni_handle->local_logger;
MESA_htable_handle tuple2stream_htable = g_kni_handle->threads_handle[thread_seq].tuple2stream_htable;
2020-10-17 17:35:46 +08:00
int flag = POLLING_STATE_IDLE;
2019-09-06 16:50:37 +08:00
//normal mode
if(g_kni_handle->deploy_mode == KNI_DEPLOY_MODE_NORMAL){
//polling tfe
for(int i = 0; i < g_kni_handle->marsio_handle->tfe_enabled_node_count; i++){
marsio_buff_t *rx_buffs[BURST_MAX];
int nr_burst = 1;
struct mr_vdev *dev_eth_handler = g_kni_handle->marsio_handle->tfe_enabled_nodes[i].dev_eth_handler;
//receive from tfe, nr_recv <= nr_burst <= BURST_MAX
int nr_recv = marsio_recv_burst(dev_eth_handler, thread_seq, rx_buffs, nr_burst);
if(nr_recv <= 0){
continue;
}
for(int j = 0; j < nr_recv; j++){
struct ethhdr *ether_hdr = (struct ethhdr*)marsio_buff_mtod(rx_buffs[j]);
2019-09-06 16:50:37 +08:00
tuple2stream_htable_search(tuple2stream_htable, ether_hdr, thread_seq);
2020-10-17 17:35:46 +08:00
flag = POLLING_STATE_WORK;
2019-09-06 16:50:37 +08:00
}
2019-09-11 17:52:47 +08:00
marsio_buff_free(g_kni_handle->marsio_handle->instance, rx_buffs, nr_recv, 0, 0);
}
2019-09-06 16:50:37 +08:00
}
//tun mode
else{
char buff[KNI_MTU];
int ret = kni_tun_read(g_kni_handle->tun_handle, buff, sizeof(buff));
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at read from tun");
}
else{
if(ret > 0){
struct ethhdr *ether_hdr = (struct ethhdr*)buff;
tuple2stream_htable_search(tuple2stream_htable, ether_hdr, thread_seq);
2020-10-17 17:35:46 +08:00
flag = POLLING_STATE_WORK;
2019-09-06 16:50:37 +08:00
}
2019-05-21 17:14:07 +08:00
}
}
2019-09-06 16:50:37 +08:00
return flag;
2019-05-21 17:14:07 +08:00
}
2019-06-14 11:13:15 +08:00
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){
2019-06-04 21:18:55 +08:00
if(ret == KNI_CMSG_INVALID_TYPE){
KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type = %d, ret = %d, stream traceid = %s, stream addr = %s",
type, ret, pmeinfo->stream_traceid, pmeinfo->stream_addr);
2019-06-04 21:18:55 +08:00
}
return -1;
}
if(value_size > value_size_max){
KNI_LOG_ERROR(logger, "kni_cmsg_get: type = %d, size = %d, which should <= %d, stream traceid = %s, stream addr = %s",
type, value_size, value_size_max, pmeinfo->stream_traceid, pmeinfo->stream_addr);
return -1;
}
switch(type)
{
case TFE_CMSG_SSL_INTERCEPT_STATE:
memcpy((char*)&(pmeinfo->ssl_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->ssl_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;
2019-06-25 09:26:33 +06:00
int can_destroy;
if(pmeinfo != NULL){
wrapped_kni_cmsg_get(pmeinfo, cmsg, TFE_CMSG_SSL_INTERCEPT_STATE, sizeof(pmeinfo->ssl_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->ssl_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);
KNI_LOG_DEBUG(logger, "recv cmsg from tfe, stream traceid = %s, stream addr = %s, stream ssl intercept state = %d ,pinning state = %d",
pmeinfo->stream_traceid, pmeinfo->stream_addr,pmeinfo->ssl_intercept_state,pmeinfo->ssl_pinningst);
if(g_kni_handle->ssl_dynamic_bypass_enable == 1){
ssl_dynamic_bypass_htable_add(pmeinfo);
}
2019-06-28 09:58:54 +06:00
can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_TFE);
2019-06-25 09:26:33 +06:00
if(can_destroy == 1){
traceid2pme_htable_del(pmeinfo);
stream_destroy(pmeinfo);
2019-06-25 09:26:33 +06:00
}
}
kni_cmsg_destroy(cmsg);
return 0;
}
2019-06-17 20:52:22 +08:00
static 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;
2019-06-17 20:52:22 +08:00
char listen_eth[KNI_SYMBOL_MAX];
uint32_t listen_ip;
int listen_port = -1;
char buff[KNI_MTU];
2019-07-31 15:06:17 +00:00
int sockfd = 0;
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 = %s, section = %s", profile, section);
goto error_out;
}
ret = MESA_load_profile_int_nodef(profile, section, "listen_port", &listen_port);
if(ret < 0){
KNI_LOG_ERROR(logger, "MESA_prof_load: listen_port not set, profile = %s, section = %s", profile, section);
goto error_out;
}
2019-06-17 20:52:22 +08:00
KNI_LOG_ERROR(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 = %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 = %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 = %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 = %d, %s", errno, strerror(errno));
continue;
}
//KNI_LOG_DEBUG(logger, "recv udp data: recv_len = %d\n", recv_len);
struct kni_cmsg *cmsg = NULL;
ret = kni_cmsg_deserialize((const unsigned char*)buff, recv_len, &cmsg);
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at deserialize cmsg, ret = %d", ret);
continue;
}
//get stream_traceid
unsigned char *stream_traceid = NULL;
uint16_t value_size;
ret = kni_cmsg_get(cmsg, TFE_CMSG_STREAM_TRACE_ID, &value_size, &stream_traceid);
if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at kni_cmsg_get: type = %d, ret = %d", TFE_CMSG_STREAM_TRACE_ID, ret);
continue;
}
//get pme
long cb_ret = -1;
struct traceid2pme_search_cb_args cb_args;
2019-06-06 17:07:17 +08:00
memset((void*)&cb_args, 0, sizeof(cb_args));
cb_args.cmsg = cmsg;
cb_args.logger = logger;
MESA_htable_search_cb(g_kni_handle->traceid2pme_htable, (const unsigned char *)stream_traceid,
2019-06-05 11:32:11 +08:00
value_size, traceid2pme_htable_search_cb, &cb_args, &cb_ret);
}
return NULL;
error_out:
if(sockfd >= 0){
close(sockfd);
}
return NULL;
}
2019-05-21 17:14:07 +08:00
static struct kni_marsio_handle* kni_marsio_init(const char* profile, int tfe_node_count){
void *logger = g_kni_handle->local_logger;
2019-05-17 17:04:50 +08:00
const char* section = "marsio";
char appsym[KNI_SYMBOL_MAX];
unsigned int opt_value = 1;
int tfe_node_enabled;
struct mr_instance *mr_inst = NULL;
struct mr_vdev *dev_eth_handler = NULL;
struct mr_sendpath *dev_eth_sendpath = NULL;
struct kni_marsio_handle *handle = NULL;
int j;
int ret = MESA_load_profile_string_nodef(profile, section, "appsym", appsym, sizeof(appsym));
if(ret < 0){
KNI_LOG_ERROR(logger, "MESA_prof_load: appsym not set, profile = %s, section = %s", profile, section);
goto error_out;
}
2019-09-06 16:50:37 +08:00
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n appsym: %s", section, appsym);
mr_inst = marsio_create();
if(mr_inst == NULL){
2019-05-21 17:14:07 +08:00
KNI_LOG_ERROR(logger, "Failed at create marsio instance");
goto error_out;
2019-05-17 17:04:50 +08:00
}
handle = ALLOC(struct kni_marsio_handle, 1);
handle->instance = mr_inst;
marsio_option_set(mr_inst, MARSIO_OPT_EXIT_WHEN_ERR, &opt_value, sizeof(opt_value));
marsio_init(mr_inst, appsym);
j = 0;
for(int i = 0; i < tfe_node_count; i++){
//load tfe conf
char _section[KNI_SYMBOL_MAX];
char dev_eth_symbol[KNI_SYMBOL_MAX];
snprintf(_section, sizeof(_section), "tfe%d", i);
MESA_load_profile_int_def(profile, _section, "enabled", &tfe_node_enabled, 1);
if(tfe_node_enabled != 1){
continue;
}
struct tfe_enabled_node tfe_node;
memset(&tfe_node, 0, sizeof(tfe_node));
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 = %s, section = %s", profile, _section);
goto error_out;
}
2019-09-06 16:50:37 +08:00
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n enabled: %d\n dev_eth_symbol: %s",
_section, tfe_node_enabled, dev_eth_symbol);
//eth_handler receive thread = thread_count, send thread = thread_count
dev_eth_handler = marsio_open_device(mr_inst, dev_eth_symbol, g_kni_handle->thread_count, g_kni_handle->thread_count);
if(dev_eth_handler == NULL){
KNI_LOG_ERROR(logger, "Failed at marsio_open_device, dev_symbol = %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 = %s", dev_eth_symbol);
goto error_out;
}
//tfe_node
tfe_node.dev_eth_handler = dev_eth_handler;
tfe_node.dev_eth_sendpath = dev_eth_sendpath;
tfe_node.tfe_id = i;
handle->tfe_enabled_nodes[j++] = tfe_node;
}
handle->tfe_enabled_node_count = j;
2019-05-17 17:04:50 +08:00
//marsio_thread_init(mr_instance);
return handle;
2019-05-21 17:14:07 +08:00
error_out:
kni_marsio_destroy(handle);
return NULL;
}
2019-05-21 17:14:07 +08:00
static void fs_destroy(struct kni_field_stat_handle *fs_handle){
if(fs_handle != NULL){
FS_stop(&(fs_handle->handle));
}
FREE(&fs_handle);
2019-05-17 17:04:50 +08:00
}
2019-05-18 12:41:31 +08:00
static struct kni_field_stat_handle * fs_init(const char *profile){
void *logger = g_kni_handle->local_logger;
2019-05-18 12:41:31 +08:00
const char *section = "field_stat";
2019-09-11 17:52:47 +08:00
char local_path[KNI_PATH_MAX];
struct kni_field_stat_handle *fs_handle = NULL;
screen_stat_handle_t handle = NULL;
char app_name[MAX_STRING_LEN]={0};
2019-11-15 20:48:23 +08:00
int value = 0, ret, stat_cycle, print_mode;
2019-09-11 17:52:47 +08:00
int remote_switch = 0;
char remote_ip[INET_ADDRSTRLEN];
int remote_port;
int statsd_format = FS_OUTPUT_STATSD;
MESA_load_profile_string_def(profile, section, "APP_NAME", app_name, sizeof(app_name), "fs2_kni");
2019-09-11 17:52:47 +08:00
MESA_load_profile_int_def(profile, section, "remote_switch", &remote_switch, 0);
MESA_load_profile_string_def(profile, section, "local_path", local_path, sizeof(local_path), "./fs2_kni.status");
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n remote_switch: %d\n local_path: %s", section, remote_switch, local_path);
handle = FS_create_handle();
2019-05-18 12:41:31 +08:00
if(handle == NULL){
KNI_LOG_ERROR(logger, "Failed at create FS_create_handle");
goto error_out;
2019-05-18 12:41:31 +08:00
}
2019-09-11 17:52:47 +08:00
if(remote_switch == 1){
ret = MESA_load_profile_string_nodef(profile, section, "remote_ip", remote_ip, sizeof(remote_ip));
if(ret < 0){
KNI_LOG_ERROR(logger, "MESA_prof_load: remote_ip not set, profile is %s, section is %s", profile, section);
goto error_out;
}
ret = MESA_load_profile_int_nodef(profile, section, "remote_port", &remote_port);
if(ret < 0){
KNI_LOG_ERROR(logger, "MESA_prof_load: remote_port not set, profile is %s, section is %s", profile, section);
goto error_out;
}
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n remote_ip: %s\n remote_port: %d", section, remote_ip, remote_port);
FS_set_para(handle, STATS_SERVER_IP, remote_ip, strlen(remote_ip));
FS_set_para(handle, STATS_SERVER_PORT, &remote_port, sizeof(remote_port));
MESA_load_profile_int_def(profile, section, "statsd_format", &statsd_format, 0);
switch(statsd_format)
{
case 1:
value=FS_OUTPUT_STATSD;
break;
case 2:
value=FS_OUTPUT_INFLUX_LINE;
break;
default:
value=FS_OUTPUT_STATSD;
}
2019-09-11 17:52:47 +08:00
FS_set_para(handle, STATS_FORMAT, &value, sizeof(value));
}
2019-11-05 14:50:53 +08:00
MESA_load_profile_int_def(profile, section, "stat_cycle", &stat_cycle, 5);
2019-11-15 20:48:23 +08:00
MESA_load_profile_int_def(profile, section, "print_mode", &print_mode, 1);
fs_handle = ALLOC(struct kni_field_stat_handle, 1);
fs_handle->handle = handle;
2019-05-18 12:41:31 +08:00
FS_set_para(handle, APP_NAME, app_name, strlen(app_name) + 1);
2019-09-11 17:52:47 +08:00
FS_set_para(handle, OUTPUT_DEVICE, local_path, strlen(local_path)+1);
value = 0;
2019-05-18 12:41:31 +08:00
FS_set_para(handle, FLUSH_BY_DATE, &value, sizeof(value));
2019-11-15 20:48:23 +08:00
value = print_mode;
2019-05-18 12:41:31 +08:00
FS_set_para(handle, PRINT_MODE, &value, sizeof(value));
value = 1;
2019-05-18 12:41:31 +08:00
FS_set_para(handle, CREATE_THREAD, &value, sizeof(value));
2019-11-05 14:50:53 +08:00
value = stat_cycle;
2019-05-18 12:41:31 +08:00
FS_set_para(handle, STAT_CYCLE, &value, sizeof(value));
value = 4096;
2019-05-18 12:41:31 +08:00
FS_set_para(handle, MAX_STAT_FIELD_NUM, &value, sizeof(value));
value=1;
FS_set_para(handle, OUTPUT_PROMETHEUS, &value, sizeof(value));
fs_handle = ALLOC(struct kni_field_stat_handle, 1);
2019-05-18 12:41:31 +08:00
fs_handle->handle = handle;
//bypass stream
2019-11-15 20:48:23 +08:00
fs_handle->fields[KNI_FIELD_BYP_INTCPERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_intcp_err");
//intercept error link mode
fs_handle->fields[KNI_FIELD_INTCPERR_GET_LINK_MODE_ERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_lkmd_get");
fs_handle->fields[KNI_FIELD_INTCPERR_NOT_LINK_MODE_BYSYN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_lkmd_not_syn");
//intercept error stream tunnel type
fs_handle->fields[KNI_FIELD_INTCPERR_GET_STREAM_TUN_TYPE_ERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tuntype_get");
fs_handle->fields[KNI_FIELD_INTCPERR_STREAM_IS_TUN_TYPE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_type_tun");
2019-11-15 20:48:23 +08:00
//intercept_error
fs_handle->fields[KNI_FIELD_INTCPERR_ASYM_ROUTING] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_asym_route");
fs_handle->fields[KNI_FIELD_INTCPERR_NO_SYN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_syn");
fs_handle->fields[KNI_FIELD_INTCPERR_NO_SYN_ACK] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_s/a");
fs_handle->fields[KNI_FIELD_INTCPERR_INVALID_IP_HDR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_ip_hdr");
fs_handle->fields[KNI_FIELD_INTCPERR_EXCEED_MTU] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_exc_mtu");
//intercept_error: internal error
fs_handle->fields[KNI_FIELD_INTCPERR_SENDTO_TFE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tfe_tx");
fs_handle->fields[KNI_FIELD_INTCPERR_TUPLE2STM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tup2stm_add");
fs_handle->fields[KNI_FIELD_INTCPERR_NO_TFE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_tfe");
fs_handle->fields[KNI_FIELD_INTCPERR_DUP_TRAFFIC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_dup_tfc");
fs_handle->fields[KNI_FIELD_INTCPERR_CMSG_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_cmsg_add");
//success intercept stream
fs_handle->fields[KNI_FIELD_INTCP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_stm");
fs_handle->fields[KNI_FIELD_INTCP_BYTE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_B");
fs_handle->fields[KNI_FIELD_IPV4_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv4_stm");
fs_handle->fields[KNI_FIELD_IPV6_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv6_stm");
2019-05-18 12:41:31 +08:00
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_DUP_TFC_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dup_tfc_stm");
fs_handle->fields[KNI_FIELD_DUP_TFC_BYTE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dup_tfc_B");
2019-11-15 20:48:23 +08:00
//intercept ready stream: success + failed
2019-09-16 16:45:25 +08:00
fs_handle->fields[KNI_FIELD_INTCP_READY_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_rdy_stm");
fs_handle->fields[KNI_FIELD_INTCP_READY_BYTE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "intcp_rdy_B");
//pme
fs_handle->fields[KNI_FIELD_PME_NEW_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "pme_new");
fs_handle->fields[KNI_FIELD_PME_FREE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "pme_free");
fs_handle->fields[KNI_FIELD_PME_CNT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "pme_cnt");
//errors
fs_handle->fields[KNI_FIELD_SENDLOG_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_sendlog");
fs_handle->fields[KNI_FIELD_ID2PME_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_id2pme_add");
fs_handle->fields[KNI_FIELD_ID2PME_DEL_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_id2pme_del");
fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tup2stm_add");
fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tup2stm_del");
fs_handle->fields[KNI_FIELD_SAPP_INJECT_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_sapp_inject");
fs_handle->fields[KNI_FIELD_BLOOM_SEARCH_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_bloom_srch");
fs_handle->fields[KNI_FIELD_BLOOM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_bloom_add");
//htable
fs_handle->fields[KNI_FIELD_ID2PME_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_add_S");
fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_del_S");
fs_handle->fields[KNI_FIELD_ID2PME_CNT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2pme_cnt");
fs_handle->fields[KNI_FIELD_TUPLE2STM_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_add_S");
fs_handle->fields[KNI_FIELD_TUPLE2STM_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_del_S");
fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_HIT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_hit");
fs_handle->fields[KNI_FIELD_TUPLE2STM_SEARCH_MISS] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "tup2stm_miss");
//sendlog
fs_handle->fields[KNI_FIELD_SENDLOG_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sendlog_S");
//sapp_inject
fs_handle->fields[KNI_FIELD_SAPP_INJECT_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "sapp_inject_S");
//dabloom
2019-09-11 17:52:47 +08:00
fs_handle->fields[KNI_FIELD_BLOOM_HIT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "bloom_hit");
fs_handle->fields[KNI_FIELD_BLOOM_MISS] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "bloom_miss");
//dynamic bypass
fs_handle->fields[KNI_FIELD_ID2SSL_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2ssl_add_S");
fs_handle->fields[KNI_FIELD_ID2SSL_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2ssl_del_S");
fs_handle->fields[KNI_FIELD_ID2SSL_CNT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "id2ssl_cnt");
fs_handle->fields[KNI_FIELD_SSL2PASS_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ssl2pass_add_S");
fs_handle->fields[KNI_FIELD_SSL2PASS_DEL_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ssl2pass_del_S");
fs_handle->fields[KNI_FIELD_SSL2PASS_CNT] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ssl2pass_cnt");
fs_handle->fields[KNI_FIELD_DY_PASS_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dy_pass_stm");
fs_handle->fields[KNI_FIELD_DY_PASS_BYTE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dy_pass_B");
fs_handle->fields[KNI_FIELD_DY_PASS_IPV6_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dy_pass_ipv6_stm");
fs_handle->fields[KNI_FIELD_DY_PASS_IPV4_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "dy_pass_ipv4_stm");
2019-09-06 16:50:37 +08:00
if(g_kni_handle->deploy_mode == KNI_DEPLOY_MODE_NORMAL){
for(int i = 0; i < g_kni_handle->marsio_handle->tfe_enabled_node_count; i++){
int tfe_id = g_kni_handle->marsio_handle->tfe_enabled_nodes[i].tfe_id;
char tfe_status[KNI_SYMBOL_MAX] = "";
snprintf(tfe_status, sizeof(tfe_status), "tfe%d", tfe_id);
fs_handle->fields[KNI_FIELD_TFE_STATUS_BASE + i] = FS_register(handle, FS_STYLE_STATUS, FS_CALC_CURRENT, tfe_status);
}
}
//table
char buff[KNI_PATH_MAX];
for(int i = 0; i < g_kni_handle->thread_count; i++){
snprintf(buff, sizeof(buff), "tid%d", i);
2019-09-11 17:52:47 +08:00
fs_handle->column_ids[i] = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff);
}
snprintf(buff, sizeof(buff), "Total");
//lines
fs_handle->column_ids[g_kni_handle->thread_count] = FS_register(handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff);
snprintf(buff, sizeof(buff), "bloom_cnt");
2019-09-11 17:52:47 +08:00
fs_handle->line_ids[0] = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff);
snprintf(buff, sizeof(buff), "tuple2stm_cnt");
fs_handle->line_ids[1] = FS_register(handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff);
2019-05-19 17:23:18 +08:00
fs_handle->handle = handle;
FS_start(handle);
2019-05-18 12:41:31 +08:00
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;
}
//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;
2019-06-25 09:26:33 +06:00
int can_destroy;
if(pmeinfo->sapp_release == 1){
2019-06-28 09:58:54 +06:00
can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_TFE);
2019-06-25 09:26:33 +06:00
if(can_destroy == 1){
2019-06-28 09:58:54 +06:00
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_DEL_SUCC], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_ID2PME_CNT], 0, FS_OP_ADD, -1);
stream_destroy(pmeinfo);
2019-06-25 09:26:33 +06:00
return 1;
}
}
return 0;
2019-05-18 12:41:31 +08:00
}
static void tuple2stream_htable_data_free_cb(void *data){
FREE(&data);
}
int dup_traffic_dabloom_init(const char *profile, void *logger){
const char *section = "dup_traffic";
MESA_load_profile_int_def(profile, section, "switch", &(g_kni_handle->dup_traffic_switch), 0);
2019-09-06 16:50:37 +08:00
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n switch: %d", section, g_kni_handle->dup_traffic_switch);
if(g_kni_handle->dup_traffic_switch == 1){
unsigned int capacity = 0;
char error_rate_str[KNI_SYMBOL_MAX];
double error_rate = 0.05;
int expiry_time = 0;
MESA_load_profile_int_def(profile, section, "action", &(g_kni_handle->dup_traffic_action), KNI_ACTION_BYPASS);
MESA_load_profile_uint_def(profile, section, "capacity", &capacity, 1000000);
MESA_load_profile_string_def(profile, section, "error_rate", error_rate_str, sizeof(error_rate_str), "0.05");
MESA_load_profile_int_def(profile, section, "expiry_time", &expiry_time, 30);
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n action: %d\n capacity: %d\n error_rate: %s\n expiry_time: %d",
2019-09-11 17:52:47 +08:00
section, g_kni_handle->dup_traffic_action, capacity, error_rate_str, expiry_time);
error_rate = atof(error_rate_str);
for(int i = 0; i < g_kni_handle->thread_count; i++){
struct expiry_dablooms_handle* dabloom_handle = expiry_dablooms_init(capacity, error_rate, expiry_time);
if(dabloom_handle == NULL){
KNI_LOG_ERROR(logger, "Failed at expiry_dablooms_init, capacity = %d,"
"error_rate = %lf, expire_time = %d", capacity, error_rate, expiry_time);
return -1;
}
g_kni_handle->threads_handle[i].dabloom_handle = dabloom_handle;
}
return 0;
}
return 0;
2019-06-09 20:00:44 +08:00
}
2019-05-18 12:41:31 +08:00
/*
void my_handler(int s){
printf("Caught signal %d\n",s);
exit(1);
}
int register_signal_handle(){
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
return 0;
}
*/
2019-05-17 17:04:50 +08:00
extern "C" int kni_init(){
//register_signal_handle();
2019-06-22 17:22:47 +08:00
char *kni_git_verison = (char*)KNI_GIT_VERSION;
const char *profile = "./etc/kni/kni.conf";
2019-05-17 17:04:50 +08:00
const char *section = "global";
2019-05-17 17:04:50 +08:00
//init logger
char log_path[KNI_PATH_MAX] = "";
2019-09-06 16:50:37 +08:00
int tfe_node_count = 1;
2019-06-21 18:55:08 +08:00
char manage_eth[KNI_SYMBOL_MAX] = "";
struct kni_field_stat_handle *fs_handle = NULL;
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;
2019-06-17 20:52:22 +08:00
struct tfe_mgr *_tfe_mgr = NULL;
char label_buff[MAX_STRING_LEN*4]={0};
tfe_cmsg_enum_to_string();
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 = %s, section = %s", profile, section);
goto error_out;
}
ret = MESA_load_profile_int_nodef(profile, section, "log_level", &log_level);
if(ret < 0){
printf("MESA_prof_load: log_level not set, profile = %s, section = %s", profile, section);
goto error_out;
2019-05-17 17:04:50 +08:00
}
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;
}
2019-09-06 16:50:37 +08:00
g_kni_handle = ALLOC(struct kni_handle, 1);
g_kni_handle->local_logger = local_logger;
2019-06-22 17:22:47 +08:00
//kni_git_log
KNI_LOG_ERROR(local_logger, "----------kni version = %s-----------", kni_git_verison);
2019-06-22 17:22:47 +08:00
2019-09-06 16:50:37 +08:00
char deploy_mode[KNI_SYMBOL_MAX];
ret = MESA_load_profile_string_def(profile, section, "deploy_mode", deploy_mode, sizeof(deploy_mode), "normal");
g_kni_handle->deploy_mode = KNI_DEPLOY_MODE_NORMAL;
if(strcmp(deploy_mode, "tun") == 0){
g_kni_handle->deploy_mode = KNI_DEPLOY_MODE_TUN;
}
if(g_kni_handle->deploy_mode == KNI_DEPLOY_MODE_NORMAL){
ret = MESA_load_profile_int_nodef(profile, section, "tfe_node_count", &tfe_node_count);
if(ret < 0){
KNI_LOG_ERROR(local_logger, "MESA_prof_load: tfe_node_count not set, profile = %s, section = %s", profile, section);
goto error_out;
}
if(tfe_node_count > TFE_COUNT_MAX){
KNI_LOG_ERROR(local_logger, "tfe_node_count = %d, exceed the max_tfe_node_count %d", tfe_node_count, TFE_COUNT_MAX);
goto error_out;
}
if(tfe_node_count <= 0){
KNI_LOG_ERROR(local_logger, "tfe_node_count = %d, <= 0", tfe_node_count);
goto error_out;
}
}
ret = MESA_load_profile_string_nodef(profile, section, "manage_eth", manage_eth, sizeof(manage_eth));
if(ret < 0){
2019-09-06 16:50:37 +08:00
printf("MESA_prof_load: manage_eth not set, profile = %s, section = %s", profile, section);
goto error_out;
}
2019-09-06 16:50:37 +08:00
char src_mac_addr_str[KNI_SYMBOL_MAX];
char dst_mac_addr_str[KNI_SYMBOL_MAX];
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(local_logger, "MESA_prof_load: src_mac_addr not set, profile = %s, section = %s", profile, section);
goto error_out;
}
ret = MESA_load_profile_string_nodef(profile, section, "dst_mac_addr", dst_mac_addr_str, sizeof(dst_mac_addr_str));
if(ret < 0){
KNI_LOG_ERROR(local_logger, "MESA_prof_load: dst_mac_addr not set, profile = %s, section = %s", profile, section);
goto error_out;
}
2019-09-06 16:50:37 +08:00
KNI_LOG_ERROR(local_logger, "MESA_prof_load, [%s]:\n log_path: %s\n log_level: %d\n tfe_node_count: %d\n manage_eth: %s\n deploy_mode: %s\n"
"src_mac_addr: %s\n dst_mac_addr: %s", section, log_path, log_level, tfe_node_count, manage_eth, deploy_mode, src_mac_addr_str, dst_mac_addr_str);
//ff:ee:dd:cc:bb:aa ---> 0xff 0xee 0xdd 0xcc 0xbb 0xaa
ret = sscanf(src_mac_addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
&(g_kni_handle->src_mac_addr[0]), &(g_kni_handle->src_mac_addr[1]),
&(g_kni_handle->src_mac_addr[2]), &(g_kni_handle->src_mac_addr[3]),
&(g_kni_handle->src_mac_addr[4]), &(g_kni_handle->src_mac_addr[5]));
if(ret != 6){
KNI_LOG_ERROR(local_logger, "MESA_prof_load: src_mac_addr = invalid, ret = %d, profile = %s, section = %s", ret, profile, section);
goto error_out;
}
2019-09-06 16:50:37 +08:00
ret = sscanf(dst_mac_addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
&(g_kni_handle->dst_mac_addr[0]), &(g_kni_handle->dst_mac_addr[1]),
&(g_kni_handle->dst_mac_addr[2]), &(g_kni_handle->dst_mac_addr[3]),
&(g_kni_handle->dst_mac_addr[4]), &(g_kni_handle->dst_mac_addr[5]));
if(ret != 6){
KNI_LOG_ERROR(local_logger, "MESA_prof_load: dst_mac_addr = invalid, ret = %d, profile = %s, section = %s", ret, profile, section);
goto error_out;
}
2019-05-17 17:04:50 +08:00
// get thread count
g_kni_handle->thread_count = get_thread_count();
if(g_kni_handle->thread_count <= 0){
KNI_LOG_ERROR(local_logger, "Failed at get_thread_count, ret = %d");
goto error_out;
}
2019-05-17 17:04:50 +08:00
//init marsio
2019-09-06 16:50:37 +08:00
if(g_kni_handle->deploy_mode == KNI_DEPLOY_MODE_NORMAL){
g_kni_handle->marsio_handle = kni_marsio_init(profile, tfe_node_count);
if(g_kni_handle->marsio_handle == NULL){
KNI_LOG_ERROR(local_logger, "Failed at init marsio");
goto error_out;
}
}
2019-09-06 16:50:37 +08:00
//init tun
if(g_kni_handle->deploy_mode == KNI_DEPLOY_MODE_TUN){
if(g_kni_handle->thread_count != 1){
KNI_LOG_ERROR(local_logger, "Tun mode, thread count must be 1, while it's %d", g_kni_handle->thread_count);
goto error_out;
}
2019-09-06 16:50:37 +08:00
char tun_name[KNI_SYMBOL_MAX];
ret = MESA_load_profile_string_nodef(profile, section, "tun_name", tun_name, sizeof(tun_name));
if(ret < 0){
KNI_LOG_ERROR(local_logger, "MESA_prof_load: tun_name not set, profile = %s, section = %s", profile, section);
goto error_out;
}
KNI_LOG_ERROR(local_logger, "MESA_prof_load, [%s]:\n tun_name: %s", section, tun_name);
g_kni_handle->tun_handle = kni_tun_init(tun_name, KNI_TUN_MODE_NOBLOCK, local_logger);
if(g_kni_handle->tun_handle == NULL){
KNI_LOG_ERROR(local_logger, "Failed at init kni_tun");
goto error_out;
}
}
2019-11-15 20:48:23 +08:00
2019-05-18 12:41:31 +08:00
//init_filedstat
fs_handle = fs_init(profile);
2019-05-18 12:41:31 +08:00
if(fs_handle == NULL){
KNI_LOG_ERROR(local_logger, "Failed at init field_stat");
goto error_out;
2019-05-18 12:41:31 +08:00
}
g_kni_fs_handle = fs_handle;
//init traceid2pme_htable
struct kni_htable_opt opt;
memset(&opt, 0, sizeof(opt));
kni_get_htable_opt(&opt, profile, "traceid2pme_htable", NULL, (void*)traceid2pme_htable_expire_notify_cb, local_logger);
2019-11-05 15:32:50 +08:00
traceid2pme_htable = kni_create_htable((char*)"traceid2pme_htable", &opt, 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;
2019-06-09 20:00:44 +08:00
//init tuple2stream_htable
g_kni_handle->threads_handle = ALLOC(struct per_thread_handle, g_kni_handle->thread_count);
memset(&opt, 0, sizeof(opt));
kni_get_htable_opt(&opt, profile, "tuple2stream_htable", (void*)tuple2stream_htable_data_free_cb, NULL, local_logger);
for(int i = 0; i < g_kni_handle->thread_count; i++){
2019-11-05 15:32:50 +08:00
MESA_htable_handle tuple2stream_htable = kni_create_htable((char*)"tuple2stream_htable", &opt, local_logger);
if(tuple2stream_htable == NULL){
KNI_LOG_ERROR(local_logger, "Failed at kni_create_htable, table = tuple2stream_htable");
2019-06-09 20:00:44 +08:00
goto error_out;
}
g_kni_handle->threads_handle[i].tuple2stream_htable = tuple2stream_htable;
}
//init ssl dynamic bypass htable
ret = ssl_dynamic_bypass_htable_init(profile, local_logger);
if(ret < 0){
goto error_out;
}
//init dabloom_handle
ret = dup_traffic_dabloom_init(profile, local_logger);
if(ret < 0){
goto error_out;
2019-06-09 20:00:44 +08:00
}
//init array last_tfe_dispatch_index and read security policy id for tsg-diagnose shunt
MESA_load_profile_int_def(profile, "tsg_diagnose", "enabled", &g_kni_handle->tsg_diagnose_enable, 1);
KNI_LOG_ERROR(local_logger, "tsg_diagnose: MESA_prof_load, tsg_diagnose:\n enabled: %d", g_kni_handle->tsg_diagnose_enable);
g_kni_handle->arr_last_tfe_dispatch_index = ALLOC(int,g_kni_handle->thread_count);
memset(&g_kni_handle->secpolicyid_shunt_tsg_diagnose, 0, sizeof(g_kni_handle->secpolicyid_shunt_tsg_diagnose));
ret = MESA_load_profile_uint_range(profile, "tsg_diagnose", "security_policy_id", TSG_DIAGNOSE_POLICY_CNT, (unsigned int *)g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_arr);
g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_num = ret;
if(ret <= 0){
KNI_LOG_ERROR(local_logger, "Fail get security_policy_id for tsg diagnose, tsg_diagnose no action to security policy id");
}
else{
for(int i = 0; i < g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_num; i++){
if(g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_arr[i] <= 0)
KNI_LOG_ERROR(local_logger, "Tsg diagnose, security policy id is not allowed to be equal to and to be lesser than 0");
else{
KNI_LOG_ERROR(local_logger, "tsg_diagnose: MESA_prof_load, tsg_diagnose: policy id:%d",g_kni_handle->secpolicyid_shunt_tsg_diagnose.id_arr[i]);
}
}
}
//init proxy tcp option maat
ret = pxy_tcp_option_rule_init(profile, local_logger);
if(ret < 0){
KNI_LOG_ERROR(local_logger, "Failed at init pxy_tcp_option_rule");
goto error_out;
}
//register customer for share session attribute
MESA_load_profile_string_def(profile, "share_session_attribute", "SESSION_ATTRIBUTE_LABEL", label_buff, sizeof(label_buff), "TSG_MASTER_INTERNAL_LABEL");
g_kni_handle->session_attribute_id = project_customer_register(label_buff, PROJECT_VAL_TYPE_STRUCT);
if(g_kni_handle->session_attribute_id < 0)
{
KNI_LOG_ERROR(local_logger,"Register %s failed; please check :%s ",label_buff,profile);
return -1;
}
2019-06-17 20:52:22 +08:00
//init tfe_mgr
2019-09-06 16:50:37 +08:00
_tfe_mgr = tfe_mgr_init(tfe_node_count, profile, g_kni_handle->deploy_mode, local_logger);
2019-06-17 20:52:22 +08:00
if(_tfe_mgr == NULL){
KNI_LOG_ERROR(local_logger, "Failed at init tfe_mgr");
goto error_out;
}
g_kni_handle->_tfe_mgr = _tfe_mgr;
2019-06-09 20:00:44 +08:00
//create thread_tfe_cmsg_receiver
cmsg_receiver_args = ALLOC(struct thread_tfe_cmsg_receiver_args, 1);
cmsg_receiver_args->logger = local_logger;
strncpy(cmsg_receiver_args->profile, profile, strnlen(profile, sizeof(cmsg_receiver_args->profile) - 1));
ret = pthread_create(&thread_id, NULL, thread_tfe_cmsg_receiver, (void *)cmsg_receiver_args);
if(unlikely(ret != 0)){
KNI_LOG_ERROR(local_logger, "Failed at pthread_create, thread_func = thread_tfe_cmsg_receiver, errno = %d, errmsg = %s", errno, strerror(errno));
2019-06-09 20:00:44 +08:00
FREE(&cmsg_receiver_args);
goto error_out;
}
2019-05-17 17:04:50 +08:00
return 0;
error_out:
if(g_kni_handle->arr_last_tfe_dispatch_index)
FREE(&(g_kni_handle->arr_last_tfe_dispatch_index));
kni_destroy(g_kni_handle);
2019-09-07 20:21:50 +08:00
exit(0);
2019-06-04 16:37:42 +08:00
}