diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 899cc1e..02c2574 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(common STATIC src/kni_utils.cpp src/ssl_utils.cpp src/kni_cmsg.cpp) +add_library(common STATIC src/kni_utils.cpp src/kni_cmsg.cpp) target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_link_libraries(common MESA_handle_logger) diff --git a/common/include/kni_utils.h b/common/include/kni_utils.h index 5fc1478..9442c75 100644 --- a/common/include/kni_utils.h +++ b/common/include/kni_utils.h @@ -22,7 +22,6 @@ #define KNI_STRING_MAX 2048 #define KNI_PATH_MAX 256 #define KNI_SYMBOL_MAX 64 -#define KNI_DOMAIN_MAX 256 #define KNI_ADDR_MAX 128 #ifndef MAX @@ -71,26 +70,20 @@ struct kni_tcpopt_info{ #define KNI_FS_COLUMN_MAX 256 #define KNI_FS_LINE_MAX 256 enum kni_field{ - KNI_FIELD_BYP_STM, - KNI_FIELD_BYP_STM_POLICY, - KNI_FIELD_BYP_STM_ERR, - //stream error - KNI_FIELD_STMERR_ASYM_ROUTING, - KNI_FIELD_STMERR_NO_SYN, - KNI_FIELD_STMERR_NO_SYN_ACK, - KNI_FIELD_STMERR_NO_DATA, - KNI_FIELD_STMERR_UNSUPPORTED_PROTOCOL, - KNI_FIELD_STMERR_INVALID_IP_HDR, - KNI_FIELD_STMERR_EXCEED_MTU, - //stream error: internal error - KNI_FIELD_STMERR_INVALID_ACTION, - KNI_FIELD_STMERR_SENDTO_TFE_FAIL, - KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL, - KNI_FIELD_STMERR_NO_TFE, - KNI_FIELD_STMERR_PME_INIT_FAIL, - KNI_FIELD_STMERR_DUP_TRAFFIC, - KNI_FIELD_STMERR_CMSG_ADD_FAIL, - //intercept stream + KNI_FIELD_BYP_INTCPERR, + //intercept error + KNI_FIELD_INTCPERR_ASYM_ROUTING, + KNI_FIELD_INTCPERR_NO_SYN, + KNI_FIELD_INTCPERR_NO_SYN_ACK, + KNI_FIELD_INTCPERR_INVALID_IP_HDR, + KNI_FIELD_INTCPERR_EXCEED_MTU, + //intercept error: internal error + KNI_FIELD_INTCPERR_SENDTO_TFE_FAIL, + KNI_FIELD_INTCPERR_TUPLE2STM_ADD_FAIL, + KNI_FIELD_INTCPERR_NO_TFE, + KNI_FIELD_INTCPERR_DUP_TRAFFIC, + KNI_FIELD_INTCPERR_CMSG_ADD_FAIL, + //success intercept stream KNI_FIELD_INTCP_STM, KNI_FIELD_INTCP_BYTE, KNI_FIELD_SSL_STM, @@ -154,6 +147,7 @@ struct pkt_info{ uint16_t tcphdr_len; char *data; uint16_t data_len; + int parse_failed; }; enum kni_ipv4hdr_parse_error{ diff --git a/common/include/ssl_utils.h b/common/include/ssl_utils.h deleted file mode 100644 index 8f55d01..0000000 --- a/common/include/ssl_utils.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -struct cipher_suite -{ - int value; - const char* name; -}; - -enum chello_parse_result -{ - CHELLO_PARSE_SUCCESS = 0, - CHELLO_PARSE_INVALID_FORMAT = -1, - CHELLO_PARSE_NOT_ENOUGH_BUFF = -2 -}; - -struct ssl_version -{ - uint8_t minor; - uint8_t major; - uint16_t ossl_format; -}; - -struct ssl_chello -{ - struct ssl_version min_version; - struct ssl_version max_version; - - char* sni; - char* alpn; - char* cipher_suites; - char* cipher_suites_tls13; -}; -struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result); - -void ssl_chello_free(struct ssl_chello* chello); \ No newline at end of file diff --git a/common/src/ssl_utils.cpp b/common/src/ssl_utils.cpp deleted file mode 100644 index 785ab48..0000000 --- a/common/src/ssl_utils.cpp +++ /dev/null @@ -1,466 +0,0 @@ -#include "kni_utils.h" -#include "ssl_utils.h" - -struct cipher_suite cipher_suite_list[] = -{ - {0xC030, "ECDHE-RSA-AES256-GCM-SHA384"}, - {0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"}, - {0xC028, "ECDHE-RSA-AES256-SHA384"}, - {0xC024, "ECDHE-ECDSA-AES256-SHA384"}, - {0xC014, "ECDHE-RSA-AES256-SHA"}, - {0xC00A, "ECDHE-ECDSA-AES256-SHA"}, - {0x00A5, "DH-DSS-AES256-GCM-SHA384"}, - {0x00A3, "DHE-DSS-AES256-GCM-SHA384"}, - {0x00A1, "DH-RSA-AES256-GCM-SHA384"}, - {0x009F, "DHE-RSA-AES256-GCM-SHA384"}, - {0x006B, "DHE-RSA-AES256-SHA256"}, - {0x006A, "DHE-DSS-AES256-SHA256"}, - {0x0069, "DH-RSA-AES256-SHA256"}, - {0x0068, "DH-DSS-AES256-SHA256"}, - {0x0039, "DHE-RSA-AES256-SHA"}, - {0x0038, "DHE-DSS-AES256-SHA"}, - {0x0037, "DH-RSA-AES256-SHA"}, - {0x0036, "DH-DSS-AES256-SHA"}, - {0x0088, "DHE-RSA-CAMELLIA256-SHA"}, - {0x0087, "DHE-DSS-CAMELLIA256-SHA"}, - {0x0086, "DH-RSA-CAMELLIA256-SHA"}, - {0x0085, "DH-DSS-CAMELLIA256-SHA"}, - {0xC019, "AECDH-AES256-SHA"}, - {0x00A7, "ADH-AES256-GCM-SHA384"}, - {0x006D, "ADH-AES256-SHA256"}, - {0x003A, "ADH-AES256-SHA"}, - {0x0089, "ADH-CAMELLIA256-SHA"}, - {0xC032, "ECDH-RSA-AES256-GCM-SHA384"}, - {0xC02E, "ECDH-ECDSA-AES256-GCM-SHA384"}, - {0xC02A, "ECDH-RSA-AES256-SHA384"}, - {0xC026, "ECDH-ECDSA-AES256-SHA384"}, - {0xC00F, "ECDH-RSA-AES256-SHA"}, - {0xC005, "ECDH-ECDSA-AES256-SHA"}, - {0x009D, "AES256-GCM-SHA384"}, - {0x003D, "AES256-SHA256"}, - {0x0035, "AES256-SHA"}, - {0x0084, "CAMELLIA256-SHA"}, - {0x008D, "PSK-AES256-CBC-SHA"}, - {0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"}, - {0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"}, - {0xC027, "ECDHE-RSA-AES128-SHA256"}, - {0xC023, "ECDHE-ECDSA-AES128-SHA256"}, - {0xC013, "ECDHE-RSA-AES128-SHA"}, - {0xC009, "ECDHE-ECDSA-AES128-SHA"}, - {0x00A4, "DH-DSS-AES128-GCM-SHA256"}, - {0x00A2, "DHE-DSS-AES128-GCM-SHA256"}, - {0x00A0, "DH-RSA-AES128-GCM-SHA256"}, - {0x009E, "DHE-RSA-AES128-GCM-SHA256"}, - {0x0067, "DHE-RSA-AES128-SHA256"}, - {0x0040, "DHE-DSS-AES128-SHA256"}, - {0x003F, "DH-RSA-AES128-SHA256"}, - {0x003E, "DH-DSS-AES128-SHA256"}, - {0x0033, "DHE-RSA-AES128-SHA"}, - {0x0032, "DHE-DSS-AES128-SHA"}, - {0x0031, "DH-RSA-AES128-SHA"}, - {0x0030, "DH-DSS-AES128-SHA"}, - {0x009A, "DHE-RSA-SEED-SHA"}, - {0x0099, "DHE-DSS-SEED-SHA"}, - {0x0098, "DH-RSA-SEED-SHA"}, - {0x0097, "DH-DSS-SEED-SHA"}, - {0x0045, "DHE-RSA-CAMELLIA128-SHA"}, - {0x0044, "DHE-DSS-CAMELLIA128-SHA"}, - {0x0043, "DH-RSA-CAMELLIA128-SHA"}, - {0x0042, "DH-DSS-CAMELLIA128-SHA"}, - {0xC018, "AECDH-AES128-SHA"}, - {0x00A6, "ADH-AES128-GCM-SHA256"}, - {0x006C, "ADH-AES128-SHA256"}, - {0x0034, "ADH-AES128-SHA"}, - {0x009B, "ADH-SEED-SHA"}, - {0x0046, "ADH-CAMELLIA128-SHA"}, - {0xC031, "ECDH-RSA-AES128-GCM-SHA256"}, - {0xC02D, "ECDH-ECDSA-AES128-GCM-SHA256"}, - {0xC029, "ECDH-RSA-AES128-SHA256"}, - {0xC025, "ECDH-ECDSA-AES128-SHA256"}, - {0xC00E, "ECDH-RSA-AES128-SHA"}, - {0xC004, "ECDH-ECDSA-AES128-SHA"}, - {0x009C, "AES128-GCM-SHA256"}, - {0x003C, "AES128-SHA256"}, - {0x002F, "AES128-SHA"}, - {0x0096, "SEED-SHA"}, - {0x0041, "CAMELLIA128-SHA"}, - {0x008C, "PSK-AES128-CBC-SHA"}, - {0xC012, "ECDHE-RSA-DES-CBC3-SHA"}, - {0xC008, "ECDHE-ECDSA-DES-CBC3-SHA"}, - {0x0016, "EDH-RSA-DES-CBC3-SHA"}, - {0x0013, "EDH-DSS-DES-CBC3-SHA"}, - {0x0010, "DH-RSA-DES-CBC3-SHA"}, - {0x000D, "DH-DSS-DES-CBC3-SHA"}, - {0xC017, "AECDH-DES-CBC3-SHA"}, - {0x001B, "ADH-DES-CBC3-SHA"}, - {0xC00D, "ECDH-RSA-DES-CBC3-SHA"}, - {0xC003, "ECDH-ECDSA-DES-CBC3-SHA"}, - {0x000A, "DES-CBC3-SHA"}, - {0x0007, "IDEA-CBC-SHA"}, - {0x008B, "PSK-3DES-EDE-CBC-SHA"}, - {0x0021, "KRB5-IDEA-CBC-SHA"}, - {0x001F, "KRB5-DES-CBC3-SHA"}, - {0x0025, "KRB5-IDEA-CBC-MD5"}, - {0x0023, "KRB5-DES-CBC3-MD5"}, - {0xC011, "ECDHE-RSA-RC4-SHA"}, - {0xC007, "ECDHE-ECDSA-RC4-SHA"}, - {0xC016, "AECDH-RC4-SHA"}, - {0x0018, "ADH-RC4-MD5"}, - {0xC00C, "ECDH-RSA-RC4-SHA"}, - {0xC002, "ECDH-ECDSA-RC4-SHA"}, - {0x0005, "RC4-SHA"}, - {0x0004, "RC4-MD5"}, - {0x008A, "PSK-RC4-SHA"}, - {0x0020, "KRB5-RC4-SHA"}, - {0x0024, "KRB5-RC4-MD5"}, - {0xC010, "ECDHE-RSA-NULL-SHA"}, - {0xC006, "ECDHE-ECDSA-NULL-SHA"}, - {0xC015, "AECDH-NULL-SHA"}, - {0xC00B, "ECDH-RSA-NULL-SHA"}, - {0xC001, "ECDH-ECDSA-NULL-SHA"}, - {0x003B, "NULL-SHA256"}, - {0x0002, "NULL-SHA"}, - {0x0001, "NULL-MD5"} -}; - -struct cipher_suite cipher_suite_list_tls13[] = -{ - {0x1301, "TLS_AES_128_GCM_SHA256"}, - {0x1302, "TLS_AES_256_GCM_SHA384"}, - {0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, - {0x1304, "TLS_AES_128_CCM_SHA256"}, - {0x1305, "TLS_AES_128_CCM_8_SHA256"} -}; - -void ssl_chello_free(struct ssl_chello* chello) -{ - if(chello==NULL) - { - return; - } - free(chello->sni); - chello->sni = NULL; - free(chello->alpn); - chello->alpn = NULL; - free(chello->cipher_suites); - chello->cipher_suites = NULL; - free(chello->cipher_suites_tls13); - chello->cipher_suites_tls13 = NULL; - free(chello); -} - -static char* parse_alpn_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) -{ - size_t pos = 0; - size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; - if(2 + len != buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return NULL; - } - char* alpn = ALLOC(char, len + 1); - strncpy((char*)alpn, (const char*)buff + 2, len); - alpn[len] = '\0'; - *result = CHELLO_PARSE_SUCCESS; - return alpn; -} - -static char* parse_server_name_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) -{ - size_t pos = 2; /* skip server name list length */ - size_t len; - char* sni = NULL; - while (pos + 3 < buff_len) - { - len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2]; - if (pos + 3 + len > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return NULL; - } - switch (buff[pos]) - { - case 0x00: /* host_name */ - sni = (char*)malloc(len + 1); - strncpy(sni, (const char*)buff + pos + 3, len); - sni[len] = '\0'; - *result = CHELLO_PARSE_SUCCESS; - } - pos += 3 + len; - } - if (pos != buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - } - return sni; -} - -static enum chello_parse_result parse_extensions(const unsigned char* buff, size_t buff_len, struct ssl_chello* chello) { - size_t pos = 0; - /* Parse each 4 bytes for the extension header */ - while (pos + 4 <= buff_len) - { - size_t len = ((size_t)buff[pos + 2] << 8) + (size_t)buff[pos + 3]; - /* Check if it's a server name extension */ - if (buff[pos] == 0x00 && buff[pos + 1] == 0x00) - { - if (pos + 4 + len > buff_len) - { - return CHELLO_PARSE_INVALID_FORMAT; - } - enum chello_parse_result result = CHELLO_PARSE_SUCCESS; - chello->sni = parse_server_name_extension(buff + pos + 4, len, &result); - if(result != CHELLO_PARSE_SUCCESS) - { - return result; - } - } - /* Check if it's a alpn extension */ - if (buff[pos] == 0x00 && buff[pos + 1] == 0x10) - { - if (pos + 4 + len > buff_len) - { - return CHELLO_PARSE_INVALID_FORMAT; - } - enum chello_parse_result result = CHELLO_PARSE_SUCCESS; - chello->alpn = parse_alpn_extension(buff + pos + 4, len, &result); - if(result != CHELLO_PARSE_SUCCESS) - { - return result; - } - } - pos += (4 + len); - } - /* Check we ended where we expected to */ - if (pos != buff_len) - { - return CHELLO_PARSE_INVALID_FORMAT; - } - return CHELLO_PARSE_SUCCESS; -} - -static char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n, const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) -{ - char* cipher_suites_str = (char* )malloc(KNI_STRING_MAX); - cipher_suites_str[0] = '\0'; - size_t pos = 0; - int flag = 0; - while(pos < buff_len) - { - int i = 0; - for(i = 0;i < n; i++) - { - int val = (buff[pos] << 8) + buff[pos + 1]; - if(_cipher_suite_list[i].value == val) - { - if(strnlen(_cipher_suite_list[i].name, KNI_STRING_MAX) + strnlen(cipher_suites_str, KNI_STRING_MAX) + 1 > KNI_STRING_MAX) - { - flag = 1; - break; - } - strncat(cipher_suites_str, _cipher_suite_list[i].name, KNI_STRING_MAX); - strncat(cipher_suites_str, ":", KNI_STRING_MAX); - } - } - pos += 2; - if(flag == 1) - { - break; - } - } - int len = strnlen(cipher_suites_str, KNI_STRING_MAX); - if(len > 0) - { - cipher_suites_str[len-1] = '\0'; - } - if(pos != buff_len && flag == 0) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - free(cipher_suites_str); - return NULL; - } - *result = CHELLO_PARSE_SUCCESS; - return cipher_suites_str; -} - -struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) -{ - if(buff == NULL) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return NULL; - } - if(buff_len < 1) - { - *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; - return NULL; - } - if(buff[0] != 0x80 && buff[0] != 0x16) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return NULL; - } - /* SSL 2.0 compatible Client Hello - * High bit of first byte (length) and content type is Client Hello - * See RFC5246 Appendix E.2 - * if it is SSL 2.0, only parse version - */ - if(buff[0] == 0x80) - { - struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); - _chello->min_version.major = 0x02; - if(buff_len < 2) - { - *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; - return _chello; - } - size_t len = (size_t)buff[1]; - if (buff_len < len + 2) - { - *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; - return _chello; - } - buff_len = len + 2; - size_t pos = 2; - /* Handshark Message Type: Client Hello */ - if (pos + 1 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - if (buff[pos] != 0x01) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - pos += 1; - /* Version */ - if(pos + 2 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - _chello->max_version.major = buff[pos]; - _chello->max_version.minor = buff[pos + 1]; - _chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor; - *result = CHELLO_PARSE_SUCCESS; - return _chello; - } - else - { - if (buff_len < 5) - { - *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; - return NULL; - } - if(buff[1] != 3 || buff[2] > 4 || buff[2] < 0) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return NULL; - } - struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); - _chello->min_version.major = buff[1]; - _chello->min_version.minor = buff[2]; - _chello->min_version.ossl_format=(uint16_t)_chello->min_version.major<<8|_chello->min_version.minor; - _chello->max_version.major = -1; - _chello->max_version.minor = -1; - _chello->sni = NULL; - _chello->alpn = NULL; - _chello->cipher_suites = NULL; - _chello->cipher_suites_tls13 = NULL; - /* TLS record length */ - size_t len = ((size_t)buff[3] << 8) + (size_t)buff[4] + 5; - if (buff_len < len) - { - *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; - return _chello; - } - buff_len = len; - size_t pos = 5; - if (pos + 1 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - if (buff[pos] != 0x01) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - pos += 4; - if(pos + 2 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - _chello->max_version.major = buff[pos]; - _chello->max_version.minor = buff[pos+1]; - _chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor; - - pos += 34; - /* Session ID */ - if (pos + 1 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - len = (size_t)buff[pos]; - pos += 1 + len; - /* Cipher Suites */ - if (pos + 2 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; - pos += 2; - if(pos + len > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - int n = sizeof(cipher_suite_list) / sizeof(struct cipher_suite); - _chello->cipher_suites = parse_cipher_suites(cipher_suite_list, n, buff + pos, len, result); - if(*result != CHELLO_PARSE_SUCCESS) - { - return _chello; - } - n = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite); - _chello->cipher_suites_tls13 = parse_cipher_suites(cipher_suite_list_tls13, n, buff + pos, len, result); - if(*result != CHELLO_PARSE_SUCCESS) - { - return _chello; - } - pos += len; - /* Compression Methods */ - if (pos >= buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - len = (size_t)buff[pos]; - pos += 1 + len; - /* no extensions */ - if(pos == buff_len) - { - *result = CHELLO_PARSE_SUCCESS; - return _chello; - } - /* Extensions */ - if (pos + 2 > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; - pos += 2; - if (pos + len > buff_len) - { - *result = CHELLO_PARSE_INVALID_FORMAT; - return _chello; - } - enum chello_parse_result ret = parse_extensions(buff + pos, len, _chello); - *result = ret; - return _chello; - } -} diff --git a/conf/sapp/kni/kni.conf b/conf/sapp/kni/kni.conf index 4c1edc1..8dc6287 100644 --- a/conf/sapp/kni/kni.conf +++ b/conf/sapp/kni/kni.conf @@ -99,4 +99,5 @@ remote_switch = 1 remote_ip = 192.168.10.152 remote_port = 8125 local_path = ./fs2_kni.status -stat_cycle = 2 \ No newline at end of file +stat_cycle = 2 +print_mode = 1 \ No newline at end of file diff --git a/entry/CMakeLists.txt b/entry/CMakeLists.txt index 8a8eb0f..d3d584d 100644 --- a/entry/CMakeLists.txt +++ b/entry/CMakeLists.txt @@ -1,3 +1,3 @@ -add_library(kni SHARED src/kni_entry.cpp src/kni_maat.cpp src/kni_send_logger.cpp src/tfe_mgr.cpp src/kni_tun.cpp) +add_library(kni SHARED src/kni_entry.cpp src/kni_send_logger.cpp src/tfe_mgr.cpp src/kni_tun.cpp) target_include_directories(kni PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_link_libraries(kni common MESA_prof_load MESA_htable MESA_field_stat maatframe marsio uuid cjson rdkafka dabloom) \ No newline at end of file diff --git a/entry/include/kni_maat.h b/entry/include/kni_maat.h deleted file mode 100644 index 7569ff7..0000000 --- a/entry/include/kni_maat.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#define KNI_MAAT_READCONF_IRIS 0 -#define KNI_MAAT_READCONF_JSON 1 -#define KNI_MAAT_READCONF_REDIS 2 -#define KNI_MAAT_RULE_NUM_MAX 8 -struct kni_maat_handle; - - -/* action - 0x00: none - 0x01: monitor - 0x02: intercept - 0x10: reject - 0x30: Manipulate - 0x60: steer - 0x80: bypass -*/ -enum kni_action{ - KNI_ACTION_NONE = 0x00, - KNI_ACTION_MONITOR = 0x01, - KNI_ACTION_INTERCEPT = 0x02, - KNI_ACTION_REJECT = 0x10, - KNI_ACTION_MANIPULATE = 0x30, - KNI_ACTION_STEER = 0x60, - KNI_ACTION_BYPASS = 0x80 -}; - -struct kni_maat_handle* kni_maat_init(const char* profile, void *logger, int thread_count); -void kni_maat_destroy(struct kni_maat_handle *handle); -enum kni_action intercept_policy_scan(struct kni_maat_handle* handle, struct ipaddr *addr, char *domain, int domain_len, - int thread_seq, int *policy_id, int *do_log, int *is_hit_policy); -char* kni_maat_action_trans(enum kni_action action); diff --git a/entry/include/tsg_rule.h b/entry/include/tsg_rule.h new file mode 100644 index 0000000..f7cfcf3 --- /dev/null +++ b/entry/include/tsg_rule.h @@ -0,0 +1,46 @@ +#ifndef __TSG_RULE_H__ +#define __TSG_RULE_H__ + +#include +#include "tsg_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MAX_DOAMIN_LEN 2048 + +struct _identify_info +{ + tsg_protocol_t proto; //enum _tsg_protocol (tsg_types.h) + int domain_len; + char domain[MAX_DOAMIN_LEN]; +}; + +typedef enum _PULL_RESULT_TYPE +{ + PULL_KNI_RESULT, + PULL_FW_RESULT +}PULL_RESULT_TYPE; + +extern Maat_feather_t g_tsg_maat_feather; + +int tsg_rule_init(const char *conffile); + +int tsg_scan_nesting_addr(Maat_feather_t maat_feather, const struct streaminfo *a_stream, tsg_protocol_t proto, scan_status_t *mid, Maat_rule_t*result, int result_num); + +//return 0 if failed, return >0 on success; +int tsg_pull_policy_result(struct streaminfo *a_stream, PULL_RESULT_TYPE pull_result_type, Maat_rule_t *result, int result_num, struct _identify_info *identify_info); + +//return -1 if failed, return 0 on success; +int tsg_shared_table_init(const char *conffile, Maat_feather_t maat_feather, void *logger); + +//return value: -1: failed, 0: not hit, >0: hit count +int tsg_scan_shared_policy(Maat_feather_t maat_feather, void *pkt, int pkt_len, Maat_rule_t *result, int result_num, struct _identify_info *identify_info, scan_status_t *mid, void *logger, int thread_seq); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/entry/include/tsg_types.h b/entry/include/tsg_types.h new file mode 100644 index 0000000..0967ef3 --- /dev/null +++ b/entry/include/tsg_types.h @@ -0,0 +1,109 @@ +#ifndef __TSG_TYPES_H__ +#define __TSG_TYPES_H__ + +typedef enum _tsg_opt +{ + LOG_OPT_HTTP_URL=1, + LOG_OPT_HTTP_HOST, + LOG_OPT_HTTP_REQUEST_LINE, + LOG_OPT_HTTP_RESPONSE_LINE, + LOG_OPT_HTTP_REQUEST_HEADER, + LOG_OPT_HTTP_RESPONSE_HEADER, + LOG_OPT_HTTP_REQUEST_BODY, + LOG_OPT_HTTP_RESPONSE_BODY, + LOG_OPT_HTTP_PROXY_FLAG, + LOG_OPT_HTTP_SEQUENCE, + LOG_OPT_HTTP_SNAPSHOT, + LOG_OPT_HTTP_COOKIE, + LOG_OPT_HTTP_REFERER, + LOG_OPT_HTTP_USER_AGENT, + LOG_OPT_HTTP_CONTENT_LENGTH, + LOG_OPT_HTTP_CONTENT_TYPE, + LOG_OPT_HTTP_SET_COOKIE, + LOG_OPT_HTTP_VERSION, + + LOG_OPT_MAIL_PROTOCOL_TYPE, + LOG_OPT_MAIL_SENDER, + LOG_OPT_MAIL_RECEIVER, + LOG_OPT_MAIL_SUBJECT, + LOG_OPT_MAIL_CONTENT, + LOG_OPT_MAIL_ATTACHMENT_NAME, + LOG_OPT_MAIL_ATTACHMENT_CONTENT, + LOG_OPT_MAIL_EML_FILE, + LOG_OPT_MAIL_SNAPSHOT, + LOG_OPT_MAIL_SUBJECT_CHARSET, + + LOG_OPT_DNS_MESSAGE_ID, + LOG_OPT_DNS_QR, + LOG_OPT_DNS_OPCODE, + LOG_OPT_DNS_AA, + LOG_OPT_DNS_TC, + LOG_OPT_DNS_RD, + LOG_OPT_DNS_RA, + LOG_OPT_DNS_RCODE, + LOG_OPT_DNS_QDCOUNT, + LOG_OPT_DNS_ANCOUNT, + LOG_OPT_DNS_NSCOUNT, + LOG_OPT_DNS_ARCOUNT, + LOG_OPT_DNS_QNAME, + LOG_OPT_DNS_QTYPE, + LOG_OPT_DNS_QCLASS, + LOG_OPT_DNS_CNAME, + LOG_OPT_DNS_SUB, + LOG_OPT_DNS_RR, + + LOG_OPT_SSL_VERSION, + LOG_OPT_SSL_SNI, + LOG_OPT_SSL_SAN, + LOG_OPT_SSL_CN, + LOG_OPT_SSL_PINNINGST, + LOG_OPT_SSL_INTERCEPT_STATE, + LOG_OPT_SSL_SERVER_SIDE_LATENCY, + LOG_OPT_SSL_CLINET_SIDE_LATENCY, + LOG_OPT_SSL_SERVER_SIDE_VERSION, + LOG_OPT_SSL_CLIENT_SIDE_VERSION, + LOG_OPT_SSL_CERT_VERIFY, + LOG_OPT_SSL_ERROR, + LOG_OPT_SSL_CON_LATENCY_MS, + + LOG_OPT_FTP_URL, + LOG_OPT_FTP_CONTENT, + + LOG_OPT_BGP_TYPE, + LOG_OPT_BGP_AS_NUM, + LOG_OPT_BGP_ROUTE, + + LOG_OPT_VOIP_CALLING_ACCOUNT, + LOG_OPT_VOIP_CALLED_ACCOUNT, + LOG_OPT_VOIP_CALLING_NUMBER, + LOG_OPT_VOIP_CALLED_NUMBER, + + LOG_OPT_RADIUS_PACKET_TYPE, + LOG_OPT_RADIUS_NAS_IP, + LOG_OPT_RADIUS_FRAMED_IP, + LOG_OPT_RADIUS_ACCOUNT, + LOG_OPT_RADIUS_SEESION_TIMEOUT, + LOG_OPT_RADIUS_IDLE_TIMEOUT, + LOG_OPT_RADIUS_ACCT_STATUS_TYPE, + LOG_OPT_RADIUS_ACCT_TERMINATE_CAUSE, + LOG_OPT_MAX +}tsg_opt_t; + +typedef enum _tsg_protocol +{ + PROTO_IPv4, + PROTO_IPv6, + PROTO_TCP, + PROTO_UDP, + PROTO_HTTP, + PROTO_MAIL, + PROTO_DNS, + PROTO_FTP, + PROTO_SSL, + PROTO_SIP, + PROTO_BGP, + PROTO_STREAMING_MEDIA, + PROTO_MAX +}tsg_protocol_t; + +#endif diff --git a/entry/src/kni_entry.cpp b/entry/src/kni_entry.cpp index e3f7fa8..c9f8fa6 100644 --- a/entry/src/kni_entry.cpp +++ b/entry/src/kni_entry.cpp @@ -3,16 +3,14 @@ intercept: destroy_pme + send_log + del traceid2pem + del tuple2stream bypass: drome: pme_new_fail: destroy_pme no_tfe: destroy_pme - stream_error: destroy_pme + send_log + intercept_error: destroy_pme + send_log giveme: policy: destroy_pme + send_log dup_traffic: destroy_pme + send_log */ #include "kni_utils.h" -#include "ssl_utils.h" #include "marsio.h" -#include "kni_maat.h" #include "MESA/http.h" #include "MESA/stream_inc/sapp_inject.h" #include "kni_cmsg.h" @@ -22,6 +20,9 @@ bypass: drome: pme_new_fail: destroy_pme #include #include #include "tfe_mgr.h" +#include "tsg_rule.h" +//#include "tsg_rule.h" + #ifdef __cplusplus extern "C" { #endif @@ -40,34 +41,42 @@ struct kni_field_stat_handle *g_kni_fs_handle = NULL; #define CALLER_SAPP 0 #define CALLER_TFE 1 - -enum kni_protocol{ - KNI_PROTOCOL_UNKNOWN = 0, - KNI_PROTOCOL_SSL, - KNI_PROTOCOL_HTTP, +enum intercept_error{ + INTERCEPT_ERROR_ASYM_ROUTING = -1, + INTERCEPT_ERROR_NO_SYN = -2, + INTERCEPT_ERROR_NO_SYN_ACK = -3, + INTERCEPT_ERROR_INVALID_IP_HDR = -4, + INTERCEPT_ERROR_EXCEED_MTU = -5, + //internal + INTERCEPT_ERROR_SENDTO_TFE_FAIL = -6, + INTERCEPT_ERROR_TUPLE2STM_ADD_FAIL = -7, + INTERCEPT_ERROR_NO_TFE = -8, + INTERCEPT_ERROR_DUP_TRAFFIC = -9, + INTERCEPT_ERROR_CMSG_ADD_FAIL = -10, }; -enum stream_error{ - STREAM_ERROR_ASYM_ROUTING = -1, - STREAM_ERROR_NO_SYN = -2, - STREAM_ERROR_NO_SYN_ACK = -3, - STREAM_ERROR_NO_DATA = -4, - STREAM_ERROR_UNSUPPORTED_PROTOCOL = -5, - STREAM_ERROR_INVALID_IP_HDR = -6, - STREAM_ERROR_EXCEED_MTU = -7, - //internal - STREAM_ERROR_INVALID_ACTION = -8, - STREAM_ERROR_SENDTO_TFE_FAIL = -9, - STREAM_ERROR_TUPLE2STM_ADD_FAIL = -10, - STREAM_ERROR_NO_TFE = -11, - STREAM_ERROR_PME_INIT_FAIL= -12, - STREAM_ERROR_DUP_TRAFFIC = -13, - STREAM_ERROR_CMSG_ADD_FAIL = -14, +/* action + 0x00: none + 0x01: monitor + 0x02: intercept + 0x10: reject + 0x30: Manipulate + 0x60: steer + 0x80: bypass +*/ +enum kni_action{ + KNI_ACTION_NONE = 0x00, + KNI_ACTION_MONITOR = 0x01, + KNI_ACTION_INTERCEPT = 0x02, + KNI_ACTION_REJECT = 0x10, + KNI_ACTION_MANIPULATE = 0x30, + KNI_ACTION_STEER = 0x60, + KNI_ACTION_BYPASS = 0x80 }; struct http_project{ int host_len; - char host[KNI_DOMAIN_MAX]; + char host[MAX_DOAMIN_LEN]; }; //memset 0 @@ -85,10 +94,9 @@ struct dup_traffic_dabloom_key{ struct pme_info{ addr_type_t addr_type; char stream_addr[KNI_ADDR_MAX]; - int protocol; int do_log; int policy_id; - int maat_hit; + tsg_protocol_t protocol; enum kni_action action; int service; struct kni_tcpopt_info client_tcpopt; @@ -99,13 +107,14 @@ struct pme_info{ uint16_t server_window; int tfe_id; pthread_mutex_t lock; - enum stream_error error; + enum intercept_error intcp_error; char stream_traceid[STREAM_TRACEID_LEN]; //cjson check protocol union{ - char host[KNI_DOMAIN_MAX]; //http only - char sni[KNI_DOMAIN_MAX]; //ssl only + char host[MAX_DOAMIN_LEN]; //http only + char sni[MAX_DOAMIN_LEN]; //ssl only }domain; + int domain_len; //tfe_release = 1: tfe don't need pmeinfo int tfe_release; int sapp_release; @@ -162,7 +171,7 @@ struct kni_marsio_handle{ struct protocol_identify_result{ int protocol; - char domain[KNI_DOMAIN_MAX]; + char domain[MAX_DOAMIN_LEN]; int domain_len; }; @@ -209,36 +218,28 @@ struct traceid2pme_search_cb_args{ void *logger; }; -static char* stream_errmsg_session_record(enum stream_error _errno){ +static char* stream_errmsg_session_record(enum intercept_error _errno){ switch(_errno){ - case STREAM_ERROR_ASYM_ROUTING: + case INTERCEPT_ERROR_ASYM_ROUTING: return (char*)"e_asym_routing"; - case STREAM_ERROR_NO_SYN: + case INTERCEPT_ERROR_NO_SYN: return (char*)"e_no_syn"; - case STREAM_ERROR_NO_SYN_ACK: + case INTERCEPT_ERROR_NO_SYN_ACK: return (char*)"e_no_synack"; - case STREAM_ERROR_NO_DATA: - return (char*)"e_no_data"; - case STREAM_ERROR_UNSUPPORTED_PROTOCOL: - return (char*)"e_unsupported_protocol"; - case STREAM_ERROR_INVALID_IP_HDR: + case INTERCEPT_ERROR_INVALID_IP_HDR: return (char*)"e_invalid_ip_hdr"; - case STREAM_ERROR_EXCEED_MTU: + case INTERCEPT_ERROR_EXCEED_MTU: return (char*)"e_exceed_mtu"; - case STREAM_ERROR_INVALID_ACTION: + case INTERCEPT_ERROR_SENDTO_TFE_FAIL: return (char*)"e_internal_1"; - case STREAM_ERROR_SENDTO_TFE_FAIL: + case INTERCEPT_ERROR_TUPLE2STM_ADD_FAIL: return (char*)"e_internal_2"; - case STREAM_ERROR_TUPLE2STM_ADD_FAIL: + case INTERCEPT_ERROR_NO_TFE: return (char*)"e_internal_3"; - case STREAM_ERROR_NO_TFE: + case INTERCEPT_ERROR_DUP_TRAFFIC: return (char*)"e_internal_4"; - case STREAM_ERROR_PME_INIT_FAIL: + case INTERCEPT_ERROR_CMSG_ADD_FAIL: return (char*)"e_internal_5"; - case STREAM_ERROR_DUP_TRAFFIC: - return (char*)"e_internal_6"; - case STREAM_ERROR_CMSG_ADD_FAIL: - return (char*)"e_internal_7"; default: return (char*)"unknown error"; } @@ -304,23 +305,19 @@ static int pme_info_init(struct pme_info *pmeinfo, const struct streaminfo *stre snprintf(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid), "%d%lld.%.9ld", thread_seq, (long long)pmeinfo->start_time.tv_sec, pmeinfo->start_time.tv_nsec); pmeinfo->addr = layer_addr_dup(&(stream->addr)); - //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); - goto error_out; - } 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)); } - //KNI_LOG_INFO(logger, "stream addr = %s, stream traceid = %s", pmeinfo->stream_addr, pmeinfo->stream_traceid); + //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; - -error_out: - return -1; } static int log_generate(struct pme_info *pmeinfo, void *local_logger){ @@ -336,7 +333,7 @@ static int log_generate(struct pme_info *pmeinfo, void *local_logger){ cJSON_AddNumberToObject(log_obj, "service", pmeinfo->service); //start_time cJSON_AddNumberToObject(log_obj, "start_time", pmeinfo->start_time.tv_sec); - if(pmeinfo->error >= 0){ + if(pmeinfo->intcp_error >= 0){ //end_time cJSON_AddNumberToObject(log_obj, "end_time", pmeinfo->end_time.tv_sec); //con_duration_ms @@ -410,11 +407,11 @@ static int log_generate(struct pme_info *pmeinfo, void *local_logger){ //addr_list cJSON_AddStringToObject(log_obj, "addr_list", ""); //host: http_only - if(pmeinfo->protocol == KNI_PROTOCOL_HTTP){ + if(pmeinfo->protocol == PROTO_HTTP){ cJSON_AddStringToObject(log_obj, "host", pmeinfo->domain.host); } //sni: ssl only - if(pmeinfo->protocol == KNI_PROTOCOL_SSL){ + if(pmeinfo->protocol == PROTO_SSL){ cJSON_AddStringToObject(log_obj, "sni", pmeinfo->domain.sni); } //c2s_pkt_num @@ -427,10 +424,10 @@ static int log_generate(struct pme_info *pmeinfo, void *local_logger){ cJSON_AddNumberToObject(log_obj, "s2c_byte_num", pmeinfo->client_bytes); //dup_traffic cJSON_AddNumberToObject(log_obj, "has_dup_traffic", pmeinfo->has_dup_traffic); - //stream_error - if(pmeinfo->error < 0){ - char *stream_errmsg = stream_errmsg_session_record(pmeinfo->error); - cJSON_AddStringToObject(log_obj, "stream_error", stream_errmsg); + //intercept_error + if(pmeinfo->intcp_error < 0){ + char *stream_errmsg = stream_errmsg_session_record(pmeinfo->intcp_error); + cJSON_AddStringToObject(log_obj, "intercept_error", stream_errmsg); } int ret = -1; char *log_msg = cJSON_PrintUnformatted(log_obj); @@ -499,38 +496,6 @@ static int judge_stream_can_destroy(struct pme_info *pmeinfo, int caller){ return can_destroy; } -static int protocol_identify(const struct streaminfo* stream, char *buf, int len, struct protocol_identify_result *result){ - //http - struct http_project* project = (struct http_project*)project_req_get_struct(stream, g_kni_handle->http_project_id); - if(project != NULL){ - result->protocol = KNI_PROTOCOL_HTTP; - result->domain_len = project->host_len; - strncpy(result->domain, project->host, strnlen(project->host, sizeof(result->domain) - 1)); - return 0; - } - - //ssl - enum chello_parse_result chello_status = CHELLO_PARSE_INVALID_FORMAT; - struct ssl_chello *chello = NULL; - chello = ssl_chello_parse((const unsigned char*)buf, len, &chello_status); - if(chello_status == CHELLO_PARSE_SUCCESS){ - result->protocol = KNI_PROTOCOL_SSL; - if(chello->sni == NULL){ - result->domain_len = 0; - } - else{ - result->domain_len = strnlen(chello->sni, KNI_DOMAIN_MAX); - strncpy(result->domain, chello->sni, strnlen(chello->sni, sizeof(result->domain) - 1)); - } - ssl_chello_free(chello); - return 0; - } - - ssl_chello_free(chello); - result->protocol = KNI_PROTOCOL_UNKNOWN; - return 0; -} - static 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); @@ -544,7 +509,7 @@ static unsigned char* kni_cmsg_serialize_header_new(struct pme_info *pmeinfo, st void *logger = g_kni_handle->local_logger; uint16_t bufflen = 0, serialize_len = 0; unsigned char *buff = NULL; - uint8_t protocol_type = pmeinfo->protocol == KNI_PROTOCOL_SSL ? 0x1 : 0x0; + uint8_t protocol_type = pmeinfo->protocol == PROTO_SSL ? 0x1 : 0x0; struct kni_cmsg *cmsg = kni_cmsg_init(); int policy_id = -1; char *trace_id = NULL; @@ -787,29 +752,27 @@ static int send_to_tfe(char *raw_data, uint16_t raw_len, int thread_seq, int tfe return ret; } -static int wrapped_kni_header_parse(const void *a_packet, struct pme_info *pmeinfo, struct pkt_info *pktinfo){ +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; 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_DEBUG(logger, "Stream error: failed at parse ipv6 header, errmsg = %s, stream treaceid = %s", + KNI_LOG_DEBUG(logger, "Intercept error: failed at parse ipv6 header, errmsg = %s, stream treaceid = %s", errmsg, pmeinfo->stream_traceid); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); - return -1; + pktinfo->parse_failed = 1; } } 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, "Stream error: failed at parse ipv4 header, errmsg = %s, stream treaceid = %s", + KNI_LOG_ERROR(logger, "Intercept error: failed at parse ipv4 header, errmsg = %s, stream treaceid = %s", errmsg, pmeinfo->stream_traceid); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV4HDR_PARSE_FAIL], 0, FS_OP_ADD, 1); - return -1; + pktinfo->parse_failed = 1; } } - return 0; + return; } static int tuple2stream_htable_key_get_v4_by_packet(struct pkt_info *pktinfo, struct stream_tuple4_v4 *key, int *reversed){ @@ -935,51 +898,9 @@ static int tuple2stream_htable_add(addr_type_t addr_type, struct pkt_info *pktin return ret; } - -static char pending_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){ - void *logger = g_kni_handle->local_logger; - struct pkt_info pktinfo; - int ret = wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo); - if(ret < 0){ - pmeinfo->error = STREAM_ERROR_INVALID_IP_HDR; - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_INVALID_IP_HDR], 0, FS_OP_ADD, 1); - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } - if(!pktinfo.tcphdr->syn){ - //pending_opstate not syn, bypass and dropme - KNI_LOG_DEBUG(logger, "Stream error: pending opstate, not 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_STMERR_NO_SYN], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_NO_SYN; - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } - - //dup traffic detect - if(g_kni_handle->dup_traffic_switch == 1){ - if(pmeinfo->syn_packet == NULL){ - struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1); - dup_traffic_dabloom_key_get(&pktinfo, syn_packet); - pmeinfo->syn_packet = syn_packet; - } - else{ - struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1); - dup_traffic_dabloom_key_get(&pktinfo, syn_packet); - if(memcmp(pmeinfo->syn_packet, syn_packet, sizeof(*syn_packet)) == 0){ - pmeinfo->has_dup_syn = 1; - } - FREE(&(pmeinfo->syn_packet)); - pmeinfo->syn_packet = syn_packet; - } - } - pmeinfo->client_window = ntohs(pktinfo.tcphdr->window); - pmeinfo->has_syn = 1; - kni_get_tcpopt(&(pmeinfo->client_tcpopt), pktinfo.tcphdr, pktinfo.tcphdr_len); - return APP_STATE_FAWPKT | APP_STATE_GIVEME; -} - static int traceid2pme_htable_add(struct pme_info *pmeinfo){ void *logger = g_kni_handle->local_logger; - int key_size =0, ret; + 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); @@ -1063,7 +984,56 @@ static void traceid2pme_htable_del(struct pme_info *pmeinfo){ } } -static int first_data_intercept(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_info *pktinfo, char *stream_addr, int thread_seq){ +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: no tfe + pmeinfo->tfe_id = tfe_mgr_alive_node_get(g_kni_handle->_tfe_mgr, 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; + } + //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; + 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; + } //dup_traffic_check if(g_kni_handle->dup_traffic_switch == 1){ //has dup traffic @@ -1072,61 +1042,50 @@ static int first_data_intercept(struct streaminfo *stream, struct pme_info *pmei } if(pmeinfo->has_dup_traffic == 1){ if(g_kni_handle->dup_traffic_action == KNI_ACTION_BYPASS){ - KNI_LOG_DEBUG(g_kni_handle->local_logger, "Stream error: stream has dup traffic, dup_traffic_action = bypass, " + 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); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_DUP_TRAFFIC], 0, FS_OP_ADD, 1); - pmeinfo->intercept_state=0; - pmeinfo->error = STREAM_ERROR_DUP_TRAFFIC; - return APP_STATE_FAWPKT | APP_STATE_DROPME; + 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; } } } - void *logger = g_kni_handle->local_logger; - int ret; - //only intercept: add to tuple2stream_htable + //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); if(ret < 0){ - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL], 0, FS_OP_ADD, 1); - KNI_LOG_DEBUG(logger, "Stream error: tuple2stm add fail, stream traceid = %s, stream addr = %s", + 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); - pmeinfo->intercept_state=0; - pmeinfo->error = STREAM_ERROR_TUPLE2STM_ADD_FAIL; - return APP_STATE_FAWPKT | APP_STATE_DROPME; + pmeinfo->intcp_error = INTERCEPT_ERROR_TUPLE2STM_ADD_FAIL; + goto error_out; } - - //only intercept: add to traceid2pme htable + //Note: traceid2pme_add_fail, still work. no cmsg traceid2pme_htable_add(pmeinfo); - //action = KNI_ACTION_INTERCEPT, sendto tfe - int len = 0; - //add cmsg - char *buff = add_cmsg_to_packet(pmeinfo, stream, pktinfo, &len); - if(buff == NULL){ - KNI_LOG_DEBUG(logger, "Stream error: failed at add cmsg to packet, stream traceid = %s, stream addr = %s", - pmeinfo->stream_traceid, pmeinfo->stream_addr); - pmeinfo->error = STREAM_ERROR_CMSG_ADD_FAIL; - pmeinfo->intercept_state=0; - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_CMSG_ADD_FAIL], 0, FS_OP_ADD, 1); - FREE(&buff); - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } //send to tfe ret = send_to_tfe(buff, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type); if(ret < 0){ - KNI_LOG_DEBUG(logger, "Stream error: failed at send first packet to tfe%d, stream traceid = %s, stream addr = %s", + 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); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1); - pmeinfo->intercept_state=0; - pmeinfo->error = STREAM_ERROR_SENDTO_TFE_FAIL; - FREE(&buff); + 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); - return APP_STATE_FAWPKT | APP_STATE_DROPME; + goto error_out; } 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); } - FREE(&buff); //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); @@ -1138,10 +1097,10 @@ static int first_data_intercept(struct streaminfo *stream, struct pme_info *pmei FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_IPV4_STM], 0, FS_OP_ADD, 1); } //http or ssl - if(pmeinfo->protocol == KNI_PROTOCOL_SSL){ + 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); } - if(pmeinfo->protocol == KNI_PROTOCOL_HTTP){ + 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 @@ -1149,7 +1108,14 @@ static int first_data_intercept(struct streaminfo *stream, struct pme_info *pmei 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); } + FREE(&buff); return APP_STATE_DROPPKT | APP_STATE_GIVEME; + +error_out: + if(buff != NULL){ + FREE(&buff); + } + return APP_STATE_FAWPKT | APP_STATE_DROPME; } static int dabloom_search(struct pkt_info *pktinfo, int thread_seq){ @@ -1179,6 +1145,36 @@ static int dabloom_search(struct pkt_info *pktinfo, int thread_seq){ return ret; } +/* action + 0x00: none + 0x01: monitor + 0x02: intercept + 0x10: reject + 0x30: Manipulate + 0x60: steer + 0x80: bypass +*/ +char* kni_maat_action_trans(enum kni_action action){ + switch(action){ + case 0x00: + return (char*)"none"; + case 0x01: + return (char*)"monitor"; + case 0x02: + return (char*)"intercept"; + case 0x10: + return (char*)"reject"; + case 0x30: + return (char*)"manipulate"; + case 0x60: + return (char*)"steer"; + case 0x80: + return (char*)"bypass"; + default: + return (char*)"unknown"; + } +} + 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; @@ -1196,6 +1192,86 @@ static int dabloom_add(struct pkt_info *pktinfo, int thread_seq){ return ret; } +void next_data_intercept(struct pme_info *pmeinfo, const void *a_packet, struct pkt_info *pktinfo, int thread_seq){ + 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; + struct iphdr *ipv4_hdr = NULL; + struct ip6_hdr* ipv6_hdr = NULL; + if(pktinfo->parse_failed == 1){ + return; + } + //search dabloom + if(g_kni_handle->dup_traffic_switch == 1){ + if(pmeinfo->has_dup_traffic == 1){ + //ret = 1, = dup packet, bypass the packet + ret = dabloom_search(pktinfo, thread_seq); + if(ret == 1){ + return; + } + } + } + if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ + ipv6_hdr = (struct ip6_hdr*)a_packet; + len = ntohs(ipv6_hdr->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr); + } + else{ + ipv4_hdr = (struct iphdr*)a_packet; + len = ntohs(ipv4_hdr->tot_len); + } + if(pktinfo.ip_totlen > KNI_DEFAULT_MTU){ + KNI_LOG_DEBUG(logger, "Next data packet exceed MTU(1500), stream traceid = %s, stream addr = %s", + pmeinfo->stream_traceid, pmeinfo->stream_addr); + return; + } + 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); + } + else{ + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_BYTE], 0, FS_OP_ADD, pktinfo->ip_totlen); + } +} + +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; + struct Maat_rule_t result; + int maat_hit = 0; + int ret = 0; + struct _identify_info identify_info; + ret = tsg_pull_policy_result(stream, PULL_KNI_RESULT, &result, 1, &identify_info); + pmeinfo->protocol = identify_info.proto; + strncpy((char*)&(pmeinfo->domain), identify_info.domain, identify_info.domain_len); + pmeinfo->domain_len = MAX(pmeinfo->domain_len, (int)sizeof(pmeinfo->domain) - 1); + pmeinfo->domain_len = '\0'; + //ret == 0, bypass and dropme + if(ret == 0){ + pmeinfo->action = KNI_ACTION_NONE; + pmeinfo->policy_id = -1; + maat_hit = 0; + } + else{ + pmeinfo->action = (enum kni_action)(result.action); + pmeinfo->policy_id = result.config_id; + pmeinfo->do_log = result.do_log; + 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, stream addr = %s", + pmeinfo->stream_addr, (char*)&(pmeinfo->domain), maat_hit, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->stream_traceid, pmeinfo->stream_addr); + switch(pmeinfo->action){ + case KNI_ACTION_INTERCEPT: + pmeinfo->intercept_state = 1; + return first_data_intercept(stream, pmeinfo, pktinfo, thread_seq); + default: + //action != intercept,bypass and dropme + return APP_STATE_FAWPKT | APP_STATE_DROPME; + } +} + static char data_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){ //pmeinfo->tfe_release = 1: intercept, tfe end first. DO NOT droppkt and dropme if(pmeinfo->tfe_release == 1){ @@ -1204,182 +1280,51 @@ static char data_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, co pmeinfo->server_pkts=stream->ptcpdetail->serverpktnum; pmeinfo->client_pkts=stream->ptcpdetail->clientpktnum; pmeinfo->dir=stream->dir; -#if 0 - return APP_STATE_DROPPKT | APP_STATE_DROPME; -#endif - } - void *logger = g_kni_handle->local_logger; - struct iphdr *ipv4_hdr = NULL; - struct ip6_hdr *ipv6_hdr = NULL; - uint16_t len = 0, ret; - char stream_addr[KNI_SYMBOL_MAX] = ""; - if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ - kni_addr_trans_v6(stream->addr.tuple4_v6, stream_addr, sizeof(stream_addr)); - } - else{ - kni_addr_trans_v4(stream->addr.tuple4_v4, stream_addr, sizeof(stream_addr)); } //parse ipv4/6 header struct pkt_info pktinfo; - ret = wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo); - if(ret < 0){ - pmeinfo->error = STREAM_ERROR_INVALID_IP_HDR; - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_INVALID_IP_HDR], 0, FS_OP_ADD, 1); - return APP_STATE_FAWPKT | APP_STATE_DROPME; + 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){ + next_data_intercept(pmeinfo, a_packet, &pktinfo, thread_seq); + return APP_STATE_DROPPKT | APP_STATE_GIVEME; } - //pmeinfo->action has only 3 value: KNI_ACTION_NONE, KNI_ACTION_INTERCEPT, KNI_ACTION_BYPASS - if(pmeinfo->action != KNI_ACTION_NONE){ - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_READY_BYTE], 0, FS_OP_ADD, pktinfo.ip_totlen); + //first data + if(stream->ptcpdetail->datalen > 0){ + return first_data_process(stream, pmeinfo, &pktinfo, thread_seq); } - switch (pmeinfo->action){ - case KNI_ACTION_NONE: - break; - case KNI_ACTION_INTERCEPT: - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_TX_TFE_BYTE], 0, FS_OP_ADD, pktinfo.ip_totlen); - //search dabloom + //before first data, may be syn/ack, ack + if(pktinfo.parse_failed == 0){ + 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 if(g_kni_handle->dup_traffic_switch == 1){ - if(pmeinfo->has_dup_traffic == 1){ - //ret = 1, = dup packet, bypass the packet - ret = dabloom_search(&pktinfo, thread_seq); - if(ret == 1){ - return APP_STATE_FAWPKT | APP_STATE_GIVEME; + if(pmeinfo->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; } } - if(pmeinfo->addr_type == ADDR_TYPE_IPV6){ - ipv6_hdr = (struct ip6_hdr*)a_packet; - len = ntohs(ipv6_hdr->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr); - } - else{ - ipv4_hdr = (struct iphdr*)a_packet; - len = ntohs(ipv4_hdr->tot_len); - } - if(pktinfo.ip_totlen > KNI_DEFAULT_MTU){ - KNI_LOG_DEBUG(logger, "Next data packet exceed MTU(1500), stream traceid = %s, stream addr = %s", - pmeinfo->stream_traceid, pmeinfo->stream_addr); - return APP_STATE_DROPPKT | APP_STATE_GIVEME; - } - 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_STMERR_SENDTO_TFE_FAIL], 0, FS_OP_ADD, 1); - } - else{ - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_BYTE], 0, FS_OP_ADD, pktinfo.ip_totlen); - } - return APP_STATE_DROPPKT | APP_STATE_GIVEME; - case KNI_ACTION_BYPASS: - return APP_STATE_FAWPKT | APP_STATE_GIVEME; - default: - assert(0); - break; - } - //first data > 1500, bypass and dropme - if(pktinfo.ip_totlen > KNI_DEFAULT_MTU){ - pmeinfo->error = STREAM_ERROR_EXCEED_MTU; - KNI_LOG_DEBUG(logger, "Stream 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_STMERR_EXCEED_MTU], 0, FS_OP_ADD, 1); - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } - // 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 - if(g_kni_handle->dup_traffic_switch == 1){ - if(pmeinfo->syn_ack_packet == NULL){ - struct dup_traffic_dabloom_key *syn_ack_packet = ALLOC(struct dup_traffic_dabloom_key, 1); - dup_traffic_dabloom_key_get(&pktinfo, syn_ack_packet); - pmeinfo->syn_ack_packet = syn_ack_packet; - } - else{ - struct dup_traffic_dabloom_key *syn_ack_packet = ALLOC(struct dup_traffic_dabloom_key, 1); - dup_traffic_dabloom_key_get(&pktinfo, syn_ack_packet); - if(memcmp(pmeinfo->syn_ack_packet, syn_ack_packet, sizeof(*syn_ack_packet)) == 0){ - pmeinfo->has_dup_syn_ack = 1; - } - FREE(&(pmeinfo->syn_ack_packet)); - pmeinfo->syn_ack_packet = syn_ack_packet; - } - } - return APP_STATE_FAWPKT | APP_STATE_GIVEME; - } - //no data, maybe ack - if(pktinfo.data_len <= 0){ - return APP_STATE_FAWPKT | APP_STATE_GIVEME; - } - //not double dir, bypass and dropme - if(stream->dir != DIR_DOUBLE){ - KNI_LOG_DEBUG(logger, "Stream 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_STMERR_ASYM_ROUTING], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_ASYM_ROUTING; - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } - struct protocol_identify_result protocol_identify_res; - memset(&protocol_identify_res, 0, sizeof(protocol_identify_res)); - protocol_identify(stream, pktinfo.data, pktinfo.data_len, &protocol_identify_res); - pmeinfo->protocol = protocol_identify_res.protocol; - switch(pmeinfo->protocol){ - //can not identify protocol from first data packet, bypass and dropme - case KNI_PROTOCOL_UNKNOWN: - KNI_LOG_DEBUG(logger, "Stream error: failed at protocol_identify, 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_STMERR_UNSUPPORTED_PROTOCOL], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_UNSUPPORTED_PROTOCOL; - return APP_STATE_FAWPKT | APP_STATE_DROPME; - case KNI_PROTOCOL_SSL: - strncpy(pmeinfo->domain.sni, protocol_identify_res.domain, strnlen(protocol_identify_res.domain, sizeof(pmeinfo->domain.sni) - 1)); - break; - case KNI_PROTOCOL_HTTP: - strncpy(pmeinfo->domain.host, protocol_identify_res.domain, strnlen(protocol_identify_res.domain, sizeof(pmeinfo->domain.host) - 1)); - break; - default: - break; - } - //receive client hello, but no syn/ack, bypass and dropme - if(pmeinfo->has_syn == 0 || pmeinfo->has_syn_ack == 0){ - KNI_LOG_DEBUG(logger, "Stream error: %s, %s, stream traceid = %s, stream addr = %s", pmeinfo->has_syn == 0 ? "no syn" : "have syn", - pmeinfo->has_syn_ack == 0 ? "no syn/ack" : "have syn/ack", pmeinfo->stream_traceid, pmeinfo->stream_addr); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_NO_SYN_ACK], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_NO_SYN_ACK; - return APP_STATE_FAWPKT | APP_STATE_DROPME; - } - pmeinfo->action = intercept_policy_scan(g_kni_handle->maat_handle, (struct ipaddr*)(&stream->addr), - protocol_identify_res.domain, protocol_identify_res.domain_len, - thread_seq, &(pmeinfo->policy_id), &(pmeinfo->do_log), &(pmeinfo->maat_hit)); - //policy scan log - char *action_str = kni_maat_action_trans(pmeinfo->action); - KNI_LOG_INFO(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d, stream traceid = %s, stream addr = %s", - stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit, pmeinfo->stream_traceid, pmeinfo->stream_addr); - 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); - switch(pmeinfo->action){ - case KNI_ACTION_BYPASS: - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_POLICY], 0, FS_OP_ADD, 1); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); - pmeinfo->intercept_state=0; - return APP_STATE_FAWPKT | APP_STATE_GIVEME; //GIVEME: for session record - case KNI_ACTION_INTERCEPT: - pmeinfo->intercept_state=1; - return first_data_intercept(stream, pmeinfo, &pktinfo, stream_addr, thread_seq); - default: - //action != intercept && action != bypass,bypass and dropme - KNI_LOG_DEBUG(logger, "Stream error: action %d(%s) = invalid: policy_id = %d, domain = %s, stream traceid = %s, stream addr = %s", - pmeinfo->action, action_str, pmeinfo->policy_id, protocol_identify_res.domain, pmeinfo->stream_traceid, pmeinfo->stream_addr); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_INVALID_ACTION], 0, FS_OP_ADD, 1); - pmeinfo->error = STREAM_ERROR_INVALID_ACTION; - return APP_STATE_FAWPKT | APP_STATE_DROPME; + } } + return APP_STATE_FAWPKT | APP_STATE_GIVEME; } static char close_opstate(const struct streaminfo *stream, struct pme_info *pmeinfo, int thread_seq){ //close: a_packet = null, do not sendto tfe clock_gettime(CLOCK_REALTIME, &(pmeinfo->end_time)); - void *logger = g_kni_handle->local_logger; pmeinfo->server_bytes=stream->ptcpdetail->serverbytes; pmeinfo->client_bytes=stream->ptcpdetail->clientbytes; pmeinfo->server_pkts=stream->ptcpdetail->serverpktnum; @@ -1392,29 +1337,50 @@ static char close_opstate(const struct streaminfo *stream, struct pme_info *pmei strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid))); tuple2stream_htable_del(stream, thread_seq); return APP_STATE_DROPPKT | APP_STATE_DROPME; - case KNI_ACTION_BYPASS: - //KNI_LOG_DEBUG(logger, "action = bypass, set tfe_release = 1, stream_trace_id = %s", pmeinfo->stream_traceid); - pmeinfo->tfe_release = 1; - return APP_STATE_FAWPKT | APP_STATE_DROPME; - //stream has only syn, ack. no data. + //stream has no data. default: - char *action_str = kni_maat_action_trans(pmeinfo->action); - pmeinfo->error = STREAM_ERROR_NO_DATA; - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_NO_DATA], 0, FS_OP_ADD, 1); - KNI_LOG_DEBUG(logger, "Stream error: close_opstate, action %d(%s) = abnormal, stream traceid = %s, stream addr = %s", - pmeinfo->action, action_str, pmeinfo->stream_traceid, pmeinfo->stream_addr); - return APP_STATE_FAWPKT | APP_STATE_DROPME; + return APP_STATE_DROPPKT | APP_STATE_DROPME; } } +static void pending_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, const void *a_packet, int thread_seq){ + pme_info_init(pmeinfo, stream, thread_seq); + struct pkt_info pktinfo; + wrapped_kni_header_parse(a_packet, pmeinfo, &pktinfo); + if(pktinfo.parse_failed == 1){ + return; + } + if(pktinfo.tcphdr->syn){ + pmeinfo->client_window = ntohs(pktinfo.tcphdr->window); + pmeinfo->has_syn = 1; + kni_get_tcpopt(&(pmeinfo->client_tcpopt), pktinfo.tcphdr, pktinfo.tcphdr_len); + //dup traffic detect + if(g_kni_handle->dup_traffic_switch == 1){ + if(pmeinfo->syn_packet == NULL){ + struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1); + dup_traffic_dabloom_key_get(&pktinfo, syn_packet); + pmeinfo->syn_packet = syn_packet; + } + else{ + struct dup_traffic_dabloom_key *syn_packet = ALLOC(struct dup_traffic_dabloom_key, 1); + dup_traffic_dabloom_key_get(&pktinfo, syn_packet); + if(memcmp(pmeinfo->syn_packet, syn_packet, sizeof(*syn_packet)) == 0){ + pmeinfo->has_dup_syn = 1; + } + FREE(&(pmeinfo->syn_packet)); + pmeinfo->syn_packet = syn_packet; + } + } + } + return; +} + //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; int can_destroy; struct pme_info *pmeinfo = *(struct pme_info **)pme; - /* a_packet == NULL && not op_state_close, continue close: a_packet may be null, if a_packet = null, do not send to tfe */ @@ -1429,41 +1395,16 @@ extern "C" char kni_tcpall_entry(struct streaminfo *stream, void** pme, int thre 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; - //stream error: pme init fail - ret = pme_info_init(pmeinfo, stream, thread_seq); - if(ret < 0){ - KNI_LOG_DEBUG(logger, "Stream error: fail at pme_info_init, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr); - pmeinfo->error = STREAM_ERROR_PME_INIT_FAIL; - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_PME_INIT_FAIL], 0, FS_OP_ADD, 1); - goto error_out; - } - //stream error: no tfe - pmeinfo->tfe_id = tfe_mgr_alive_node_get(g_kni_handle->_tfe_mgr, thread_seq); - if(pmeinfo->tfe_id < 0){ - KNI_LOG_DEBUG(logger, "Stream error: no available tfe, stream traceid = %s, stream addr = %s", pmeinfo->stream_traceid, pmeinfo->stream_addr); - pmeinfo->error = STREAM_ERROR_NO_TFE; - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_NO_TFE], 0, FS_OP_ADD, 1); - goto error_out; - } - ret = pending_opstate(stream, pmeinfo, a_packet, thread_seq); - if(pmeinfo->error < 0){ - goto error_out; - } + pending_opstate(stream, pmeinfo, a_packet, thread_seq); + ret = APP_STATE_FAWPKT | APP_STATE_GIVEME; break; case OP_STATE_DATA: ret = data_opstate(stream, pmeinfo, a_packet, thread_seq); - //exception stream, dropme and destroy pmeinfo - if(pmeinfo->error < 0){ - goto error_out; - } break; case OP_STATE_CLOSE: //sapp stream close //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STATE_CLOSE], 0, FS_OP_ADD, 1); ret = close_opstate(stream, pmeinfo, thread_seq); - if(pmeinfo->error < 0){ - goto error_out; - } break; default: ret = APP_STATE_FAWPKT | APP_STATE_GIVEME; @@ -1473,26 +1414,36 @@ extern "C" char kni_tcpall_entry(struct streaminfo *stream, void** pme, int thre break; } //sapp release: bypass or intercept + /* 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 + */ if((ret & APP_STATE_DROPME)){ - can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_SAPP); - if(can_destroy == 1){ - if(pmeinfo->action == KNI_ACTION_INTERCEPT){ - traceid2pme_htable_del(pmeinfo); + if(pmeinfo->action != KNI_ACTION_INTERCEPT){ + if(pmeinfo != NULL){ + stream_destroy(pmeinfo, 0); + } + } + else{ + if(pmeinfo->intcp_error < 0){ + pmeinfo->intercept_state = 0; + 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; + stream_destroy(pmeinfo, 1); + } + } + else{ + can_destroy = judge_stream_can_destroy(pmeinfo, CALLER_SAPP); + if(can_destroy == 1){ + traceid2pme_htable_del(pmeinfo); + stream_destroy(pmeinfo, pmeinfo->do_log); + } } - stream_destroy(pmeinfo, pmeinfo->do_log); } } return ret; - -//error out: stream error, send log and destroy_pme, do not need to del htable -error_out: - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM_ERR], 0, FS_OP_ADD, 1); - FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); - if(pmeinfo != NULL){ - pmeinfo->policy_id = -1; - stream_destroy(pmeinfo, 1); - } - return APP_STATE_FAWPKT | APP_STATE_DROPME; } void http_project_free(int thread_seq, void *project_req_value){ @@ -1909,7 +1860,7 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ struct kni_field_stat_handle *fs_handle = NULL; screen_stat_handle_t handle = NULL; const char *app_name = "fs2_kni"; - int value = 0, ret, stat_cycle; + int value = 0, ret, stat_cycle, print_mode; int remote_switch = 0; char remote_ip[INET_ADDRSTRLEN]; int remote_port; @@ -1939,13 +1890,14 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ FS_set_para(handle, STATS_FORMAT, &value, sizeof(value)); } MESA_load_profile_int_def(profile, section, "stat_cycle", &stat_cycle, 5); + 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; FS_set_para(handle, APP_NAME, app_name, strlen(app_name) + 1); FS_set_para(handle, OUTPUT_DEVICE, local_path, strlen(local_path)+1); value = 0; FS_set_para(handle, FLUSH_BY_DATE, &value, sizeof(value)); - value = 1; + value = print_mode; FS_set_para(handle, PRINT_MODE, &value, sizeof(value)); value = 1; FS_set_para(handle, CREATE_THREAD, &value, sizeof(value)); @@ -1957,27 +1909,21 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ fs_handle->handle = handle; //bypass stream - fs_handle->fields[KNI_FIELD_BYP_STM] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_stm"); - fs_handle->fields[KNI_FIELD_BYP_STM_POLICY] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_policy"); - fs_handle->fields[KNI_FIELD_BYP_STM_ERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_stm_err"); - //stream error - fs_handle->fields[KNI_FIELD_STMERR_ASYM_ROUTING] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_asym_route"); - fs_handle->fields[KNI_FIELD_STMERR_NO_SYN] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_syn"); - fs_handle->fields[KNI_FIELD_STMERR_NO_SYN_ACK] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_s/a"); - fs_handle->fields[KNI_FIELD_STMERR_NO_DATA] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_data"); - fs_handle->fields[KNI_FIELD_STMERR_UNSUPPORTED_PROTOCOL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_unspt_pro"); - fs_handle->fields[KNI_FIELD_STMERR_INVALID_IP_HDR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_ip_hdr"); - fs_handle->fields[KNI_FIELD_STMERR_EXCEED_MTU] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_exc_mtu"); - //stream error: internal error - fs_handle->fields[KNI_FIELD_STMERR_INVALID_ACTION] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_invaid_act"); - fs_handle->fields[KNI_FIELD_STMERR_SENDTO_TFE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tfe_tx"); - fs_handle->fields[KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_tup2stm_add"); - fs_handle->fields[KNI_FIELD_STMERR_NO_TFE] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_no_tfe"); - fs_handle->fields[KNI_FIELD_STMERR_PME_INIT_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_pme_init"); - fs_handle->fields[KNI_FIELD_STMERR_DUP_TRAFFIC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_dup_tfc"); - fs_handle->fields[KNI_FIELD_STMERR_CMSG_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "e_cmsg_add"); + fs_handle->fields[KNI_FIELD_BYP_INTCPERR] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "byp_intcp_err"); + //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"); - //intercept stream + //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"); @@ -1987,7 +1933,7 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ 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"); - //intercept ready stream + //intercept ready stream: success + failed 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"); @@ -2269,14 +2215,7 @@ extern "C" int kni_init(){ goto error_out; } } - - //init maat - g_kni_handle->maat_handle = kni_maat_init(profile, local_logger, g_kni_handle->thread_count); - if(g_kni_handle->maat_handle == NULL){ - KNI_LOG_ERROR(local_logger, "Failed at init maat"); - goto error_out; - } - + //init_filedstat fs_handle = fs_init(profile); if(fs_handle == NULL){ diff --git a/entry/src/kni_maat.cpp b/entry/src/kni_maat.cpp deleted file mode 100644 index 8a667db..0000000 --- a/entry/src/kni_maat.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include "kni_utils.h" -#include "kni_maat.h" - - -enum scan_table -{ - PXY_INTERCEPT_IP, - PXY_INTERCEPT_DOMAIN, - TSG_OBJ_SUBSCRIBER_ID, - SCAN_TABLE_MAX -}; - -enum kni_action g_maat_default_action = KNI_ACTION_BYPASS; -int g_maat_default_log_option=1; -struct kni_maat_handle{ - Maat_feather_t static_maat; - Maat_feather_t dynamic_maat; - int scan_tableid[SCAN_TABLE_MAX]; - int subscriber_id_tableid; - void *logger; -}; - -void kni_maat_destroy(struct kni_maat_handle *handle){ - if(handle != NULL){ - if(handle->static_maat != NULL){ - Maat_burn_feather(handle->static_maat); - } - if(handle->dynamic_maat != NULL){ - Maat_burn_feather(handle->dynamic_maat); - } - } - FREE(&handle); -} - - -void compile_ex_param_new(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp){ - void *logger = argp; - unsigned char tmp=0; - KNI_LOG_DEBUG(logger, "call compile_ex_param_new"); - if(rule->config_id == 0){ - tmp=(unsigned char)rule->action; - enum kni_action action = (enum kni_action)tmp; - if(action==KNI_ACTION_INTERCEPT) - { - g_maat_default_action = KNI_ACTION_INTERCEPT; - KNI_LOG_INFO(logger, "Set default intercept action to intercept."); - } - else - { - g_maat_default_action = KNI_ACTION_BYPASS; - KNI_LOG_INFO(logger, "Set default intercept action to bypass."); - } - g_maat_default_log_option=rule->do_log; - } - return; -} - -void compile_ex_param_free(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp){ - void *logger = argp; - KNI_LOG_DEBUG(logger, "call compile_ex_param_free"); - return; -} - -void compile_ex_param_dup(int idx, MAAT_RULE_EX_DATA *to, MAAT_RULE_EX_DATA *from, long argl, void *argp){ - void *logger = argp; - KNI_LOG_DEBUG(logger, "call compile_ex_param_dup"); - return; -} - - -static Maat_feather_t create_maat_feather(const char *instance_name, const char* profile, const char *section, void *logger, int thread_count){ - int readconf_mode; - char tableinfo_path[KNI_PATH_MAX]; - char maatjson_path[KNI_PATH_MAX]; - char redis_ip[INET_ADDRSTRLEN]; - int redis_port; - int redis_index; - Maat_feather_t feather = NULL; - int effective_interval_ms = 1000;//1s - int ret = MESA_load_profile_int_nodef(profile, section, "readconf_mode", &readconf_mode); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: readconf_mode not set, profile = %s, section = %s", profile, section); - goto error_out; - } - ret = MESA_load_profile_string_nodef(profile, section, "tableinfo_path", tableinfo_path, sizeof(tableinfo_path)); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: tableinfo_path not set, profile = %s, section = %s", profile, section); - goto error_out; - } - KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n readconf_mode: %d\n tableinfo_path: %s" , section, readconf_mode, tableinfo_path); - feather = Maat_feather(thread_count, tableinfo_path, logger); - if(feather == NULL){ - KNI_LOG_ERROR(logger, "Failed at Maat_feather, max_thread_num = %d, tableinfo_path = %s", thread_count, tableinfo_path); - goto error_out; - } - Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, instance_name, strlen(instance_name) + 1); - Maat_set_feather_opt(feather, MAAT_OPT_EFFECT_INVERVAL_MS, &effective_interval_ms, sizeof(effective_interval_ms)); - switch(readconf_mode){ - case KNI_MAAT_READCONF_JSON: - ret = MESA_load_profile_string_nodef(profile, section, "maatjson_path", maatjson_path, sizeof(maatjson_path)); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: maatjson_path not set, profile = %s, section = %s", profile, section); - goto error_out; - } - KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n maatjson_path: %s", section, maatjson_path); - Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, maatjson_path, strlen(maatjson_path)); - break; - case KNI_MAAT_READCONF_IRIS: - break; - case KNI_MAAT_READCONF_REDIS: - ret = MESA_load_profile_string_nodef(profile, section, "redis_ip", redis_ip, sizeof(redis_ip)); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: redis_ip not set, profile = %s, section = %s", profile, section); - goto error_out; - } - ret = MESA_load_profile_int_nodef(profile, section, "redis_port", &redis_port); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: redis_port not set, profile = %s, section = %s", profile, section); - goto error_out; - } - ret = MESA_load_profile_int_nodef(profile, section, "redis_index", &redis_index); - if(ret < 0){ - KNI_LOG_ERROR(logger, "MESA_prof_load: redis_index not set, profile = %s, section = %s", profile, section); - goto error_out; - } - KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n redis_ip: %s\n redis_port: %d\n redis_index: %d", - section, redis_ip, redis_port, redis_index); - Maat_set_feather_opt(feather, MAAT_OPT_REDIS_IP, (void*)redis_ip, strlen(redis_ip) + 1); - Maat_set_feather_opt(feather, MAAT_OPT_REDIS_PORT, (void*)&redis_port, sizeof(redis_port)); - Maat_set_feather_opt(feather, MAAT_OPT_REDIS_INDEX, (void*)&redis_index, sizeof(redis_index)); - break; - default: - break; - } - ret = Maat_initiate_feather(feather); - if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at Maat_initiate_feather"); - goto error_out; - } - return feather; - -error_out: - if(feather != NULL){ - Maat_burn_feather(feather); - } - return NULL; -} - -//copy from tfe -static int get_column_pos(const char* line, int column_seq, size_t *offset, size_t *len){ - const char* seps=" \t"; - char* saveptr=NULL, *subtoken=NULL, *str=NULL; - char* dup_line=kni_strdup(line); - int i=0, ret=-1; - for (str = dup_line; ; str = NULL){ - subtoken = strtok_r(str, seps, &saveptr); - if (subtoken == NULL) - break; - if(i==column_seq-1){ - *offset=subtoken-dup_line; - *len=strlen(subtoken); - ret=0; - break; - } - i++; - } - free(dup_line); - return ret; -} - -void subscribe_id_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA* to, MAAT_PLUGIN_EX_DATA* from, long argl, void* argp){ - *to = kni_strdup((char*)*from); - return; -} - -void subscribe_id_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp){ - int ret = 0; - size_t subscribe_id_offset, len; - void *logger = argp; - ret = get_column_pos(table_line, 4, &subscribe_id_offset, &len); - if(ret<0){ - KNI_LOG_ERROR(logger, "Add subscribe ID faild: %s", table_line); - return; - } - *ad = ALLOC(char, len+1); - memcpy(*ad, table_line+subscribe_id_offset, len); - KNI_LOG_INFO(logger, "Add subscribe ID: %s", (char*)*ad); - return; -} - -void subscribe_id_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp){ - void *logger = argp; - KNI_LOG_INFO(logger, "Delete subscribe ID: %s", (char*)*ad); - free(*ad); - *ad = NULL; -} - -struct kni_maat_handle* kni_maat_init(const char* profile, void *logger, int thread_count){ - struct kni_maat_handle *handle = ALLOC(struct kni_maat_handle, 1); - handle->logger = logger; - //static maat - const char *table_name[SCAN_TABLE_MAX]; - char tablename_intercept_compile[] = "PXY_INTERCEPT_COMPILE"; - char tablename_subscriber_id[] = "TSG_DYN_SUBSCRIBER_IP"; - int ret, i; - handle->static_maat = create_maat_feather("static", profile, "static_maat", logger, thread_count); - if(handle->static_maat == NULL){ - goto error_out; - } - table_name[PXY_INTERCEPT_IP] = "PXY_INTERCEPT_IP"; - table_name[PXY_INTERCEPT_DOMAIN] = "PXY_INTERCEPT_DOMAIN"; - table_name[TSG_OBJ_SUBSCRIBER_ID] = "TSG_OBJ_SUBSCRIBER_ID"; - for(i = 0; i < SCAN_TABLE_MAX; i++){ - handle->scan_tableid[i] = Maat_table_register(handle->static_maat, table_name[i]); - if(handle->scan_tableid[i] < 0){ - KNI_LOG_ERROR(logger, "Failed at Maat_table_register, tablename = %s, ret = %d", - table_name[i], handle->scan_tableid[i]); - goto error_out; - } - } - //get_ex - ret = Maat_rule_get_ex_new_index(handle->static_maat, tablename_intercept_compile, compile_ex_param_new, compile_ex_param_free, compile_ex_param_dup, 0, logger); - if(ret < 0){ - KNI_LOG_ERROR(logger, "Failed at Maat_rule_get_ex_new_index, tablename = %s, ret = %d", tablename_intercept_compile, ret); - goto error_out; - } - //dynamic maat register - handle->dynamic_maat = create_maat_feather("dynamic", profile, "dynamic_maat", logger, thread_count); - if(handle->dynamic_maat == NULL){ - goto error_out; - } - handle->subscriber_id_tableid = Maat_table_register(handle->dynamic_maat, tablename_subscriber_id); - if(handle->subscriber_id_tableid < 0){ - KNI_LOG_ERROR(logger, "Failed at Maat_table_register, tablename = %s, ret = %d", - tablename_subscriber_id, handle->subscriber_id_tableid); - goto error_out; - } - ret = Maat_plugin_EX_register(handle->dynamic_maat, - handle->subscriber_id_tableid, - subscribe_id_new_cb, - subscribe_id_free_cb, - subscribe_id_dup_cb, - NULL, - 0, - logger); - if(ret != 0){ - KNI_LOG_ERROR(NULL, "Failed at Maat_plugin_EX_register, tablename = %s, ret = %d", tablename_subscriber_id, ret); - goto error_out; - } - return handle; - -error_out: - kni_maat_destroy(handle); - return NULL; -} - -static int index_of_enforce_policy(struct Maat_rule_t* result, size_t size){ - size_t i = 0; - int biggest_intercept_policy_id = -1, ret_intercept_idx = -1; - int biggest_bypass_policy_id = -1, ret_bypass_idx = -1; - for(i = 0; i < size; i++){ - if((unsigned char)result[i].action == KNI_ACTION_BYPASS){ - if(result[i].config_id > biggest_bypass_policy_id){ - biggest_bypass_policy_id = result[i].config_id; - ret_bypass_idx = i; - } - } - else{ - if(result[i].config_id > biggest_intercept_policy_id){ - biggest_intercept_policy_id = result[i].config_id; - ret_intercept_idx = i; - } - } - } - if(biggest_bypass_policy_id != -1){ - return ret_bypass_idx; - } - else{ - return ret_intercept_idx; - } -} - -//type: 0 : sip, 1 : dip -static void get_ip_from_ipaddr(struct ipaddr *addr, char *ip, int type){ - if(addr->addrtype == ADDR_TYPE_IPV4){ - struct stream_tuple4_v4 *v4 = addr->v4; - if(type == 0){ - inet_ntop(AF_INET, &(v4->saddr), ip, INET_ADDRSTRLEN); - } - else{ - inet_ntop(AF_INET, &(v4->daddr), ip, INET_ADDRSTRLEN); - } - } - else{ - struct stream_tuple4_v6 *v6 = addr->v6; - if(type == 0){ - inet_ntop(AF_INET6, v6->saddr, ip, INET6_ADDRSTRLEN); - } - else{ - inet_ntop(AF_INET6, v6->daddr, ip, INET6_ADDRSTRLEN); - } - } - return; -} - -enum kni_action intercept_policy_scan(struct kni_maat_handle* handle, struct ipaddr *addr, char *domain, int domain_len, - int thread_seq, int *policy_id, int *do_log, int *is_hit_policy){ - //return KNI_ACTION_INTERCEPT; - struct Maat_rule_t result[KNI_MAAT_RULE_NUM_MAX]; - scan_status_t scan_mid = NULL; - int scan_ret = 0, hit_policy_cnt = 0, enforced_policy_idx = 0; - //scan subscribe_id - char sip[INET6_ADDRSTRLEN] = ""; - char dip[INET6_ADDRSTRLEN] = ""; - get_ip_from_ipaddr(addr, sip, 0); - get_ip_from_ipaddr(addr, dip, 1); - char* source_subscribe_id = NULL, *dest_subscribe_id = NULL; - source_subscribe_id = (char*)Maat_plugin_get_EX_data(handle->dynamic_maat, handle->subscriber_id_tableid, sip); - dest_subscribe_id = (char*)Maat_plugin_get_EX_data(handle->dynamic_maat, handle->subscriber_id_tableid, dip); - KNI_LOG_DEBUG(handle->logger, "sip = %s, source_subscribe_id = %s", sip, source_subscribe_id == NULL ? "null" : source_subscribe_id); - KNI_LOG_DEBUG(handle->logger, "dip = %s, dest_subscribe_id = %s", dip, dest_subscribe_id == NULL ? "null" : dest_subscribe_id); - if(source_subscribe_id != NULL){ - scan_ret = Maat_full_scan_string(handle->static_maat, handle->scan_tableid[TSG_OBJ_SUBSCRIBER_ID], - CHARSET_UTF8, source_subscribe_id, strlen(source_subscribe_id), - result+hit_policy_cnt, NULL, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt, - &scan_mid, thread_seq); - KNI_LOG_DEBUG(handle->logger, "source_subscribe_id = %s, scan_ret = %d", source_subscribe_id, scan_ret); - if(scan_ret > 0){ - hit_policy_cnt += scan_ret; - } - free(source_subscribe_id); - } - if(dest_subscribe_id != NULL){ - scan_ret = Maat_full_scan_string(handle->static_maat, handle->scan_tableid[TSG_OBJ_SUBSCRIBER_ID], - CHARSET_UTF8, dest_subscribe_id, strlen(dest_subscribe_id), - result+hit_policy_cnt, NULL, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt, - &scan_mid, thread_seq); - KNI_LOG_DEBUG(handle->logger, "dest_subscribe_id = %s, scan_ret = %d", dest_subscribe_id, scan_ret); - if(scan_ret > 0){ - hit_policy_cnt += scan_ret; - } - free(dest_subscribe_id); - } - //tcp: 6, udp: 17, can't be 0 - scan_ret = Maat_scan_proto_addr(handle->static_maat, handle->scan_tableid[PXY_INTERCEPT_IP], addr, 6, - result+hit_policy_cnt, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt, - &scan_mid, thread_seq); - if(scan_ret > 0){ - hit_policy_cnt += scan_ret; - } - scan_ret = Maat_full_scan_string(handle->static_maat, handle->scan_tableid[PXY_INTERCEPT_DOMAIN], CHARSET_UTF8, - domain, domain_len, - result+hit_policy_cnt, NULL, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt, - &scan_mid, thread_seq); - if(scan_ret > 0){ - hit_policy_cnt += scan_ret; - } - Maat_clean_status(&scan_mid); - if(hit_policy_cnt > 0){ - enforced_policy_idx = index_of_enforce_policy(result, hit_policy_cnt); - *policy_id = result[enforced_policy_idx].config_id; - *do_log = result[enforced_policy_idx].do_log; - *is_hit_policy = 1; - unsigned char action = (unsigned char)result[enforced_policy_idx].action; - return (enum kni_action)action; - } - else{ - *policy_id = 0; - *do_log = g_maat_default_log_option; - return g_maat_default_action; - } -} - - -/* action - 0x00: none - 0x01: monitor - 0x02: intercept - 0x10: reject - 0x30: Manipulate - 0x60: steer - 0x80: bypass -*/ -char* kni_maat_action_trans(enum kni_action action){ - switch(action){ - case 0x00: - return (char*)"none"; - case 0x01: - return (char*)"monitor"; - case 0x02: - return (char*)"intercept"; - case 0x10: - return (char*)"reject"; - case 0x30: - return (char*)"manipulate"; - case 0x60: - return (char*)"steer"; - case 0x80: - return (char*)"bypass"; - default: - return (char*)"unknown"; - } -} - -