diff --git a/cache/src/tango_cache_client.cpp b/cache/src/tango_cache_client.cpp index 80a462d..cdfb1bc 100644 --- a/cache/src/tango_cache_client.cpp +++ b/cache/src/tango_cache_client.cpp @@ -47,7 +47,7 @@ void caculate_sha256(const char *data, unsigned long len, char *result, u_int32_ SHA256_Update(&c, data, len); SHA256_Final(sha256, &c); - length = (size > 64)?32:(size-1)/2; //Ԥ��һ���ռ� + length = (size > 64)?32:(size-1)/2; //Ԥһռ for(u_int32_t i=0; ibuff[estr->len]='\0'; } -//callback: �Ƿ���ûص���������ҪΪ���ֱ�ӵ���APIʱʧ�ܣ����ٵ��ûص�������ͨ������ֵ�ж� +//callback: ǷûصҪΪֱӵAPIʱʧܣٵûصֵͨж void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx, bool callback) { struct multipart_etag_list *etag; @@ -255,7 +255,7 @@ void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx, bool callback) free(ctx); } -//�ж�session�Ƿ񳬹����ƣ�����ȡ��ʼ���ж�where_to_get�Ƿ�ȫ����MINIO�� +//жsessionǷ񳬹ƣȡʼжwhere_to_getǷȫMINIO bool sessions_exceeds_limit(struct tango_cache_instance *instance, enum OBJECT_LOCATION where_to_get) { if(where_to_get == OBJECT_IN_HOS) @@ -269,7 +269,7 @@ bool sessions_exceeds_limit(struct tango_cache_instance *instance, enum OBJECT_L } -//�����ϴ�API��ʹ��ctx��evbuffer�������޷�����ctx��ȡ���� +//ϴAPIʹctxevbuffer޷ctxȡ enum OBJECT_LOCATION tango_cache_object_locate(struct tango_cache_instance *instance, size_t object_size) { if(instance->param->fsstatid_trig) @@ -340,7 +340,7 @@ int tango_cache_update_frag_data(struct tango_cache_ctx *ctx, const char *data, { if(ctx->fail_state) { - return 0; //TODO: ��ʱ���Է���ֵ!! + return 0; //TODO: ʱԷֵ!! } if(evbuffer_add(ctx->put.evbuf, data, size)) { @@ -362,7 +362,7 @@ int tango_cache_update_frag_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COP if(ctx->fail_state) { - return 0;//TODO: ��ʱ���Է���ֵ!! + return 0;//TODO: ʱԷֵ!! } size = evbuffer_get_length(evbuf); @@ -424,7 +424,7 @@ struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance * { snprintf(ctx->object_key, 256, "%s/%c%c_%c%c_%s", instance->param->bucketname, buffer[0], buffer[1], buffer[2], buffer[3], buffer+4); } - //����ԭʼURL + //ԭʼURL snprintf(buffer, 2064, "x-amz-meta-url: %s", meta->url); ctx->headers = curl_slist_append(ctx->headers, buffer); } @@ -441,7 +441,7 @@ struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance * return NULL; } - //Expires�ֶΣ����ڻ����ڲ��ж������Ƿ�ʱ + //ExpiresֶΣڻڲжǷʱ now = time(NULL); expires = (meta->put.timeout==0||meta->put.timeout>instance->param->relative_ttl)?instance->param->relative_ttl:meta->put.timeout; if(expires_timestamp2hdr_str(now + expires, buffer, 256)) @@ -449,7 +449,7 @@ struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance * ctx->headers = curl_slist_append(ctx->headers, buffer); } ctx->put.object_ttl = expires; - //Last-Modify�ֶΣ�����GETʱ�ж��Ƿ����� + //Last-ModifyֶΣGETʱжǷ last_modify = (meta->put.date > meta->put.last_modified)?meta->put.date:meta->put.last_modified; if(last_modify == 0) { @@ -457,7 +457,7 @@ struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance * } sprintf(buffer, "x-amz-meta-lm: %lu", last_modify); ctx->headers = curl_slist_append(ctx->headers, buffer); - //�б���֧�ֵı�׼ͷ�� + //бֵ֧ı׼ͷ for(int i=0; istd_hdr[i] != NULL) @@ -478,11 +478,11 @@ struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance * easy_string_savedata(&hdr_estr, "Content-Type: application/octet-stream\r\n", strlen("Content-Type: application/octet-stream\r\n")); } } - ctx->headers = curl_slist_append(ctx->headers, "Expect:");//ע��POST������Expect��ϵ��Ҫ��ȷ����CURLOPT_POSTFIELDSIZE - //���������ͷ����GETʱ��ԭ������ + ctx->headers = curl_slist_append(ctx->headers, "Expect:");//עPOSTExpectϵҪȷCURLOPT_POSTFIELDSIZE + //ͷGETʱԭ if(meta->usertag_len>0 && meta->usertag_len<=USER_TAG_MAX_LEN) { - user_tag = (char *)malloc((meta->usertag_len/3 + 1)*4 + 18); //������������ռ䣻18=17+1: ͷ��+�ַ��������� + user_tag = (char *)malloc((meta->usertag_len/3 + 1)*4 + 18); //ռ䣻18=17+1: ͷ+ַ memcpy(user_tag, "x-amz-meta-user: ", 17); user_tag_value = user_tag+17; Base64_EncodeBlock((const unsigned char*)meta->usertag, meta->usertag_len, (unsigned char*)user_tag_value); @@ -535,7 +535,7 @@ struct tango_cache_ctx *tango_cache_update_start(struct tango_cache_instance *in return ctx; } -//һ�����ϴ�ʱ��ֱ�Ӷ�λ�����ϴ���λ�� +//һϴʱֱӶλϴλ struct tango_cache_ctx *tango_cache_update_once_prepare(struct tango_cache_instance *instance, struct future* f, struct tango_cache_meta_put *meta, size_t object_size, char *path, size_t pathsize) { @@ -600,7 +600,7 @@ struct tango_cache_ctx *tango_cache_fetch_prepare(struct tango_cache_instance *i ctx = (struct tango_cache_ctx *)calloc(1, sizeof(struct tango_cache_ctx)); ctx->instance = instance; ctx->promise = future_to_promise(f); - promise_allow_many_successes(ctx->promise); //��λص��������ʱ����promise_finish + promise_allow_many_successes(ctx->promise); //λصʱpromise_finish ctx->method = method; ctx->get.state = GET_STATE_START; ctx->get.max_age = meta->get.max_age; @@ -647,7 +647,7 @@ int tango_cache_head_object(struct tango_cache_instance *instance, struct future struct tango_cache_ctx *ctx; enum OBJECT_LOCATION location; - //���������Redis����Ԫ��Ϣ�洢��Redis�� + //RedisԪϢ洢Redis location = (instance->param->object_store_way != CACHE_ALL_HOS)?OBJECT_IN_REDIS:OBJECT_IN_HOS; ctx = tango_cache_fetch_prepare(instance, CACHE_REQUEST_HEAD, f, meta, location); if(ctx == NULL) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 8c98f04..cebf8a3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -10,6 +10,7 @@ target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_include_directories(common PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../platform/include/internal) target_link_libraries(common PUBLIC libevent-static libevent-static-openssl libevent-static-pthreads rdkafka) target_link_libraries(common PUBLIC MESA_handle_logger cjson msgpack) +target_link_libraries(common PUBLIC pthread) if (SUPPORT_LIBURING) target_link_libraries(common PUBLIC uring) diff --git a/common/include/tfe_acceptor_kni.h b/common/include/tfe_acceptor_kni.h index 7bb3fb3..3871dbc 100644 --- a/common/include/tfe_acceptor_kni.h +++ b/common/include/tfe_acceptor_kni.h @@ -7,6 +7,7 @@ extern "C" #endif #include +#include // #include "proxy.h" #include "tfe_utils.h" @@ -84,35 +85,31 @@ extern "C" struct packet_info { - int dir_is_e2i; + int is_e2i_dir; struct addr_tuple4 tuple4; - char *addr_string; char *header_data; int header_len; - - struct sids sids; - struct route_ctx route_ctx; }; struct session_ctx { int policy_ids; uint64_t session_id; + char *session_addr; - uint16_t user_field; + char client_mac[6]; + char server_mac[6]; - struct route_ctx raw_pkt_i2e_route_ctx; - struct route_ctx raw_pkt_e2i_route_ctx; + struct packet_info c2s_info; + struct packet_info s2c_info; - struct sids raw_pkt_i2e_sids; - struct sids raw_pkt_e2i_sids; + struct metadata *raw_meta_i2e; + struct metadata *raw_meta_e2i; + struct metadata *ctrl_meta; - // depending on first control packet - struct packet_info first_ctrl_pkt; - - // 加锁 struct tfe_cmsg *cmsg; + struct acceptor_thread_ctx *ref_thread_ctx; }; @@ -133,10 +130,8 @@ extern "C" cpu_set_t coremask; struct tap_config *config; - struct timestamp *ts; struct packet_io *io; struct global_metrics *metrics; - struct policy_enforcer *enforcer; struct acceptor_thread_ctx work_threads[TFE_THREAD_MAX]; struct tfe_proxy *ref_proxy; diff --git a/common/include/tfe_ctrl_packet.h b/common/include/tfe_ctrl_packet.h index 2ae43db..fbdd277 100644 --- a/common/include/tfe_ctrl_packet.h +++ b/common/include/tfe_ctrl_packet.h @@ -27,6 +27,11 @@ struct ctrl_pkt_parser uint64_t sce_policy_ids[32]; int sce_policy_id_num; struct tfe_cmsg *cmsg; + + struct sids seq_sids; + struct route_ctx seq_route_ctx; + struct sids ack_sids; + struct route_ctx ack_route_ctx; }; const char *session_state_to_string(enum session_state state); diff --git a/common/include/tfe_metrics.h b/common/include/tfe_metrics.h index 32c76e7..d96277a 100644 --- a/common/include/tfe_metrics.h +++ b/common/include/tfe_metrics.h @@ -32,6 +32,14 @@ struct global_metrics struct throughput_metrics decrypt_rx; // 累计值 struct throughput_metrics ctrl_pkt_rx; // 累计值 + struct throughput_metrics ctrl_pkt_tx; // 累计值 + + struct throughput_metrics tap_pkt_rx; // 累计值 + struct throughput_metrics tap_pkt_tx; // 累计值 + struct throughput_metrics tap_c_pkt_rx; // 累计值 + struct throughput_metrics tap_c_pkt_tx; // 累计值 + struct throughput_metrics tap_s_pkt_rx; // 累计值 + struct throughput_metrics tap_s_pkt_tx; // 累计值 uint64_t ctrl_pkt_opening_num; // 累计值 uint64_t ctrl_pkt_active_num; // 累计值 diff --git a/common/src/tfe_acceptor_kni.cpp b/common/src/tfe_acceptor_kni.cpp index 13e8846..a3a54be 100644 --- a/common/src/tfe_acceptor_kni.cpp +++ b/common/src/tfe_acceptor_kni.cpp @@ -21,18 +21,6 @@ void session_ctx_free(struct session_ctx *ctx) { if (ctx) { - if (ctx->first_ctrl_pkt.addr_string) - { - free(ctx->first_ctrl_pkt.addr_string); - ctx->first_ctrl_pkt.addr_string = NULL; - } - - if (ctx->first_ctrl_pkt.header_data) - { - free(ctx->first_ctrl_pkt.header_data); - ctx->first_ctrl_pkt.header_data = NULL; - } - if (ctx->cmsg) { tfe_cmsg_destroy(ctx->cmsg); @@ -43,13 +31,11 @@ void session_ctx_free(struct session_ctx *ctx) } } - /****************************************************************************** * acceptor_ctx ******************************************************************************/ struct acceptor_ctx *acceptor_ctx_create(const char *profile) { - int ret = 0; struct acceptor_ctx *ctx = ALLOC(struct acceptor_ctx, 1); MESA_load_profile_int_def(profile, "system", "firewall_sids", (int *)&(ctx->firewall_sids), 1001); @@ -83,17 +69,6 @@ struct acceptor_ctx *acceptor_ctx_create(const char *profile) goto error_out; } - // ctx->enforcer = policy_enforcer_create("KNI", profile, ctx->nr_worker_threads, NULL); - // if (ctx->enforcer == NULL) - // { - // goto error_out; - // } - - // if (policy_enforcer_register(ctx->enforcer) == -1) - // { - // goto error_out; - // } - return ctx; error_out: @@ -107,6 +82,7 @@ void acceptor_ctx_destory(struct acceptor_ctx * ctx) { packet_io_destory(ctx->io); tfe_tap_destory(ctx->config); + global_metrics_destory(ctx->metrics); free(ctx); ctx = NULL; diff --git a/common/src/tfe_cmsg.cpp b/common/src/tfe_cmsg.cpp index 1d934f2..8b01030 100644 --- a/common/src/tfe_cmsg.cpp +++ b/common/src/tfe_cmsg.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "tfe_types.h" #include "tfe_utils.h" @@ -23,6 +24,7 @@ struct tfe_cmsg_tlv struct tfe_cmsg { + pthread_rwlock_t rwlock; uint16_t nr_tlvs; struct tfe_cmsg_tlv* tlvs[TFE_CMSG_TLV_NR_MAX]; uint16_t size; @@ -39,6 +41,8 @@ struct tfe_cmsg* tfe_cmsg_init() { struct tfe_cmsg *cmsg = ALLOC(struct tfe_cmsg, 1); cmsg->size = sizeof(struct tfe_cmsg_serialize_header); + + pthread_rwlock_init(&(cmsg->rwlock), NULL); return cmsg; } @@ -46,11 +50,15 @@ void tfe_cmsg_destroy(struct tfe_cmsg *cmsg) { if(cmsg != NULL) { + pthread_rwlock_wrlock(&cmsg->rwlock); for(int i = 0; i < TFE_CMSG_TLV_NR_MAX; i++) { FREE(&(cmsg->tlvs[i])); } + pthread_rwlock_unlock(&cmsg->rwlock); + pthread_rwlock_destroy(&cmsg->rwlock); } + FREE(&cmsg); } @@ -60,6 +68,7 @@ int tfe_cmsg_set(struct tfe_cmsg * cmsg, enum tfe_cmsg_tlv_type type, const unsi { return TFE_CMSG_INVALID_TYPE; } + pthread_rwlock_wrlock(&cmsg->rwlock); struct tfe_cmsg_tlv *tlv = cmsg->tlvs[type]; uint16_t length = sizeof(struct tfe_cmsg_tlv) + size; @@ -83,6 +92,7 @@ int tfe_cmsg_set(struct tfe_cmsg * cmsg, enum tfe_cmsg_tlv_type type, const unsi tlv->length = length; memcpy(tlv->value_as_string, value, size); cmsg->tlvs[type] = tlv; + pthread_rwlock_unlock(&cmsg->rwlock); return 0; } @@ -99,6 +109,7 @@ int tfe_cmsg_get_value(struct tfe_cmsg * cmsg, enum tfe_cmsg_tlv_type type, unsi goto errout; } + pthread_rwlock_rdlock(&cmsg->rwlock); tlv = cmsg->tlvs[type]; if (unlikely(tlv == NULL)) { @@ -115,31 +126,38 @@ int tfe_cmsg_get_value(struct tfe_cmsg * cmsg, enum tfe_cmsg_tlv_type type, unsi memcpy(out_value, tlv->value_as_string, value_length); *out_size = value_length; - + pthread_rwlock_unlock(&cmsg->rwlock); return 0; errout: + pthread_rwlock_unlock(&cmsg->rwlock); return result; } uint16_t tfe_cmsg_serialize_size_get(struct tfe_cmsg *cmsg) { - return cmsg->size; + pthread_rwlock_rdlock(&cmsg->rwlock); + uint16_t size = cmsg->size; + pthread_rwlock_unlock(&cmsg->rwlock); + return size; } int tfe_cmsg_serialize(struct tfe_cmsg *cmsg, unsigned char *buff, uint16_t bufflen, uint16_t *serialize_len) { //size是serialize之后的实际长度 + pthread_rwlock_rdlock(&cmsg->rwlock); uint16_t size = cmsg->size; //传入buff是否够长 if(bufflen < size) { + pthread_rwlock_unlock(&cmsg->rwlock); return TFE_CMSG_BUFF_NOT_ENOUGH; } //size是否正确 if(size < sizeof(struct tfe_cmsg_serialize_header)) { - return TFE_CMSG_INVALID_FORMAT; + pthread_rwlock_unlock(&cmsg->rwlock); + return TFE_CMSG_BUFF_NOT_ENOUGH; } struct tfe_cmsg_serialize_header *header = (struct tfe_cmsg_serialize_header*)buff; header->__magic__[0] = 0x4d; @@ -156,6 +174,7 @@ int tfe_cmsg_serialize(struct tfe_cmsg *cmsg, unsigned char *buff, uint16_t buff } if(count != cmsg->nr_tlvs) { + pthread_rwlock_unlock(&cmsg->rwlock); return TFE_CMSG_INVALID_FORMAT; } //序列化 @@ -168,11 +187,13 @@ int tfe_cmsg_serialize(struct tfe_cmsg *cmsg, unsigned char *buff, uint16_t buff } if(i != tlv->type) { + pthread_rwlock_unlock(&cmsg->rwlock); return TFE_CMSG_INVALID_FORMAT; } uint16_t length = tlv->length; if(length < sizeof(struct tfe_cmsg_tlv) || offset + length > size) { + pthread_rwlock_unlock(&cmsg->rwlock); return TFE_CMSG_INVALID_FORMAT; } memcpy((char*)header + offset, (void*)tlv, length); @@ -184,9 +205,11 @@ int tfe_cmsg_serialize(struct tfe_cmsg *cmsg, unsigned char *buff, uint16_t buff //检查size是否正确 if(offset != size) { + pthread_rwlock_unlock(&cmsg->rwlock); return TFE_CMSG_INVALID_FORMAT; } *serialize_len = size; + pthread_rwlock_unlock(&cmsg->rwlock); return 0; } @@ -235,7 +258,9 @@ int tfe_cmsg_deserialize(const unsigned char *data, uint16_t len, struct tfe_cms offset += length; } cmsg->size = offset; + pthread_rwlock_wrlock(&((*pcmsg)->rwlock)); *pcmsg = cmsg; + pthread_rwlock_unlock(&((*pcmsg)->rwlock)); return 0; error_out: diff --git a/common/src/tfe_ctrl_packet.cpp b/common/src/tfe_ctrl_packet.cpp index 0b6b3dc..4fed27f 100644 --- a/common/src/tfe_ctrl_packet.cpp +++ b/common/src/tfe_ctrl_packet.cpp @@ -34,7 +34,6 @@ void ctrl_packet_parser_init(struct ctrl_pkt_parser *handler) // return -1 : error int ctrl_packet_parser_parse(struct ctrl_pkt_parser *handler, const char *data, size_t length) { - // TODO FREE return parse_messagepack(data, length, handler); } @@ -59,14 +58,6 @@ void ctrl_packet_parser_dump(struct ctrl_pkt_parser *handler) { TFE_LOG_INFO(g_default_logger, "%s: %d sce policy_ids[%03lu]", LOG_TAG_POLICY, i, handler->sce_policy_ids[i]); } - - uint64_t policy_id = 0; - tfe_cmsg_get_value(handler->cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)&policy_id, 64, &cmsg_len); - TFE_LOG_INFO(g_default_logger, "TFE_CMSG_POLICY_ID: %lu", policy_id); - uint16_t client_mss = 0; - tfe_cmsg_get_value(handler->cmsg, TFE_CMSG_TCP_RESTORE_MSS_CLIENT, (unsigned char *)&client_mss, 16, &cmsg_len); - TFE_LOG_INFO(g_default_logger, "TFE_CMSG_TCP_RESTORE_MSS_CLIENT: %u", client_mss); - } } diff --git a/common/src/tfe_metrics.cpp b/common/src/tfe_metrics.cpp index 735a0a8..aebf9dd 100644 --- a/common/src/tfe_metrics.cpp +++ b/common/src/tfe_metrics.cpp @@ -19,7 +19,6 @@ enum SCE_STAT_FIELD STAT_RAW_PKT_TX_PKT, STAT_RAW_PKT_TX_B, - // steering STAT_DECRYPTED_TX_PKT, STAT_DECRYPTED_TX_B, STAT_DECRYPTED_RX_PKT, @@ -28,6 +27,23 @@ enum SCE_STAT_FIELD // control packet STAT_CONTROL_RX_PKT, STAT_CONTROL_RX_B, + STAT_CONTROL_TX_PKT, + STAT_CONTROL_TX_B, + + STAT_TAP_RX_PKT, + STAT_TAP_RX_B, + STAT_TAP_TX_PKT, + STAT_TAP_TX_B, + + STAT_TAP_C_RX_PKT, + STAT_TAP_C_RX_B, + STAT_TAP_C_TX_PKT, + STAT_TAP_C_TX_B, + + STAT_TAP_S_RX_PKT, + STAT_TAP_S_RX_B, + STAT_TAP_S_TX_PKT, + STAT_TAP_S_TX_B, STAT_CTRL_PKT_OPENING, STAT_CTRL_PKT_ACTIVE, @@ -64,6 +80,22 @@ static const char *stat_map[] = // control packet [STAT_CONTROL_RX_PKT] = "ctrl_rx_pkt", [STAT_CONTROL_RX_B] = "ctrl_rx_B", + [STAT_CONTROL_TX_PKT] = "ctrl_tx_pkt", + [STAT_CONTROL_TX_B] = "ctrl_tx_B", + + // tap packet + [STAT_TAP_RX_PKT] = "tap_rx_pkt", + [STAT_TAP_RX_B] = "tap_rx_B", + [STAT_TAP_TX_PKT] = "tap_tx_pkt", + [STAT_TAP_TX_B] = "tap_tx_B", + [STAT_TAP_C_RX_PKT] = "tap_c_rx_pkt", + [STAT_TAP_C_RX_B] = "tap_c_rx_B", + [STAT_TAP_C_TX_PKT] = "tap_c_tx_pkt", + [STAT_TAP_C_TX_B] = "tap_c_tx_B", + [STAT_TAP_S_RX_PKT] = "tap_s_rx_pkt", + [STAT_TAP_S_RX_B] = "tap_s_rx_B", + [STAT_TAP_S_TX_PKT] = "tap_s_tx_pkt", + [STAT_TAP_S_TX_B] = "tap_s_tx_B", [STAT_CTRL_PKT_OPENING] = "ctrl_pkt_open", [STAT_CTRL_PKT_ACTIVE] = "ctrl_pkt_avtive", @@ -94,7 +126,6 @@ void global_metrics_destory(struct global_metrics *metrics) { if (metrics) { - FS_library_destroy(); free(metrics); metrics = NULL; } @@ -121,6 +152,18 @@ void global_metrics_dump(struct global_metrics *metrics) // control packet FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CONTROL_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CONTROL_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CONTROL_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CONTROL_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_TX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_TX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_C_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_C_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_C_TX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_TAP_C_TX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_OPENING], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_opening_num), 0, __ATOMIC_RELAXED)); FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ACTIVE], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_active_num), 0, __ATOMIC_RELAXED)); diff --git a/common/src/tfe_mpack.cpp b/common/src/tfe_mpack.cpp index 73a7b89..f6bb9ec 100644 --- a/common/src/tfe_mpack.cpp +++ b/common/src/tfe_mpack.cpp @@ -16,18 +16,30 @@ enum ctr_pkt_index INDEX_SESSION_ID, INDEX_STATE, INDEX_METHOD, - INDEX_SCE, - INDEX_SHAPER, - INDEX_PROXY, + INDEX_KEY_SCE, + INDEX_VALUE_SCE, + INDEX_KEY_SHAPER, + INDEX_VALUE_SHAPER, + INDEX_KEY_PROXY, + INDEX_VALUE_PROXY, INDEX_MAX }; +enum { + MPACK_ARRAY_FQDN_IDS, + MPACK_ARRAY_SEQ_SIDS, + MPACK_ARRAY_ACK_SIDS, + MPACK_ARRAY_SEQ_ROUTE_CTX, + MPACK_ARRAY_ACK_ROUTE_CTX, +}; + struct mpack_mmap_id2type { int id; enum tfe_cmsg_tlv_type type; char *str_name; int size; + int array_index; }mpack_table[] = { {.id = 0, .type = TFE_CMSG_POLICY_ID, .str_name = "TFE_CMSG_POLICY_ID", .size = 8}, {.id = 1, .type = TFE_CMSG_TCP_RESTORE_SEQ, .str_name = "TFE_CMSG_TCP_RESTORE_SEQ", .size = 4}, @@ -61,49 +73,116 @@ struct mpack_mmap_id2type {.id = 29, .type = TFE_CMSG_SRC_IP_LOCATION_SUBDIVISION, .str_name = "TFE_CMSG_SRC_IP_LOCATION_SUBDIVISION", .size = 256}, {.id = 30, .type = TFE_CMSG_DST_IP_LOCATION_SUBDIVISION, .str_name = "TFE_CMSG_DST_IP_LOCATION_SUBDIVISION", .size = 256}, {.id = 31, .type = TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT, .str_name = "TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT", .size = 32}, - {.id = 32, .type = TFE_CMSG_FQDN_CAT_ID_VAL, .str_name = "TFE_CMSG_FQDN_CAT_ID_VAL", .size = 4} + {.id = 32, .type = TFE_CMSG_FQDN_CAT_ID_VAL, .str_name = "TFE_CMSG_FQDN_CAT_ID_VAL", .size = 4, .array_index = MPACK_ARRAY_FQDN_IDS}, + {.id = 33, .str_name = "TFE_SEQ_SIDS", .size = 2, .array_index = MPACK_ARRAY_SEQ_SIDS}, + {.id = 34, .str_name = "TFE_ACK_SIDS", .size = 2, .array_index = MPACK_ARRAY_ACK_SIDS}, + {.id = 35, .str_name = "TFE_SEQ_ROUTE_CTX", .size = 1, .array_index = MPACK_ARRAY_SEQ_ROUTE_CTX}, + {.id = 36, .str_name = "TFE_ACK_ROUTE_CTX", .size = 1, .array_index = MPACK_ARRAY_ACK_ROUTE_CTX} }; -static int proxy_parse_messagepack(msgpack_object obj, void *ctx) +static void fqdn_id_set_cmsg(struct ctrl_pkt_parser *handler, msgpack_object *ptr, int table_index) { - struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx; uint32_t fqdn_val[8] = {0}; - for (unsigned int i = 0; i < obj.via.array.size; i++) { - msgpack_object ptr = obj.via.array.ptr[i]; + tfe_cmsg_set(handler->cmsg, TFE_CMSG_FQDN_CAT_ID_NUM, (const unsigned char *)&ptr->via.array.size, sizeof(uint32_t)); + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu array fqdn_id num: [%u]", LOG_TAG_CTRLPKT, handler->session_id, ptr->via.array.size); + for (uint32_t j = 0; j < ptr->via.array.size; j++) { + fqdn_val[j] = ptr->via.array.ptr[j].via.u64; + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu array fqdn_id msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, handler->session_id, mpack_table[table_index].str_name, ptr->via.array.ptr[j].via.u64); + } + tfe_cmsg_set(handler->cmsg ,TFE_CMSG_FQDN_CAT_ID_VAL, (const unsigned char*)fqdn_val, ptr->via.array.size * sizeof(uint32_t)); + return; +} + +static void sids_array_parse_mpack(struct ctrl_pkt_parser *handler, msgpack_object *ptr, int table_index, int is_seq) +{ + struct sids *sid= is_seq ? &handler->seq_sids : &handler->ack_sids; + + sid->num = ptr->via.array.size > MR_SID_LIST_MAXLEN ? MR_SID_LIST_MAXLEN : ptr->via.array.size; + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu array sids num: [%u]", LOG_TAG_CTRLPKT, handler->session_id, ptr->via.array.size); + for (int i = 0; i < sid->num; i++) + { + sid->elems[i] = ptr->via.array.ptr[i].via.u64; + } + return; +} + +static void route_ctx_parse_mpack(struct ctrl_pkt_parser *handler, msgpack_object *ptr, int table_index, int is_seq) +{ + struct route_ctx *ctx = is_seq ? &handler->seq_route_ctx : &handler->ack_route_ctx; + + ctx->len = ptr->via.array.size > 64 ? 64 : ptr->via.array.size; + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu array route ctx num: [%u]", LOG_TAG_CTRLPKT, handler->session_id, ptr->via.array.size); + for (int i = 0; i < ctx->len; i++) + { + memcpy(ctx->data+i, &ptr->via.array.ptr[i].via.u64, 1); + } + return; +} + +static int proxy_parse_messagepack(msgpack_object *obj, void *ctx) +{ + struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx; + + for (unsigned int i = 0; i < obj->via.array.size; i++) { + msgpack_object *ptr = &obj->via.array.ptr[i]; if (i == 0) { - if (ptr.type == MSGPACK_OBJECT_ARRAY) { - handler->tfe_policy_id_num = ptr.via.array.size; - for (uint32_t j = 0; j < ptr.via.array.size; j++) { - handler->tfe_policy_ids[j] = ptr.via.array.ptr[j].via.u64; + if (ptr->type == MSGPACK_OBJECT_ARRAY) { + handler->tfe_policy_id_num = ptr->via.array.size; + for (uint32_t j = 0; j < ptr->via.array.size; j++) { + handler->tfe_policy_ids[j] = ptr->via.array.ptr[j].via.u64; } tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&handler->tfe_policy_ids[0], sizeof(uint64_t)); - TFE_LOG_DEBUG(g_default_logger, "%s: interger msgpack cmsg: [%s] num: [%d]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, handler->tfe_policy_id_num); + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu interger msgpack cmsg: [%s] num: [%d]", LOG_TAG_CTRLPKT, handler->session_id, mpack_table[i].str_name, handler->tfe_policy_id_num); for (int j = 0; j < handler->tfe_policy_id_num; j++) { - TFE_LOG_DEBUG(g_default_logger, "%s: policy id:%lu ", LOG_TAG_CTRLPKT, handler->tfe_policy_ids[j]); + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu policy id:%lu ", LOG_TAG_CTRLPKT, handler->session_id, handler->tfe_policy_ids[j]); } } continue; } - switch (ptr.type) { + switch (ptr->type) { case MSGPACK_OBJECT_POSITIVE_INTEGER: - tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&ptr.via.u64, mpack_table[i].size); - TFE_LOG_DEBUG(g_default_logger, "%s: interger msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.u64); + // TFE_CMSG_TCP_RESTORE_PROTOCOL tsg master 发送数据错误,临时强制设置为1 + if (i == 11) + { + uint8_t protocol = 1; + tfe_cmsg_set(handler->cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (const unsigned char *)&protocol, 1); + } + else + { + tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&ptr->via.u64, mpack_table[i].size); + } + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu interger msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, handler->session_id, mpack_table[i].str_name, ptr->via.u64); break; case MSGPACK_OBJECT_STR: - tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)ptr.via.str.ptr, ptr.via.str.size); - TFE_LOG_DEBUG(g_default_logger, "%s: string msgpack cmsg: [%s] -> [%s]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.str.ptr); + tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)ptr->via.str.ptr, ptr->via.str.size); + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu string msgpack cmsg: [%s] -> [%s]", LOG_TAG_CTRLPKT, handler->session_id, mpack_table[i].str_name, ptr->via.str.ptr); + break; + case MSGPACK_OBJECT_NIL: + TFE_LOG_DEBUG(g_default_logger, "%s: session: %lu msgpack cmsg: [%s] -> [nil]", LOG_TAG_CTRLPKT, handler->session_id, mpack_table[i].str_name); break; case MSGPACK_OBJECT_ARRAY: - if (i == 32) { - tfe_cmsg_set(handler->cmsg, TFE_CMSG_FQDN_CAT_ID_NUM, (const unsigned char *)&ptr.via.array.size, sizeof(uint32_t)); - for (uint32_t j = 0; j < ptr.via.array.size; j++) { - fqdn_val[j] = ptr.via.array.ptr[j].via.u64; - TFE_LOG_DEBUG(g_default_logger, "%s: array msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.array.ptr[j].via.u64); - } - tfe_cmsg_set(handler->cmsg ,TFE_CMSG_FQDN_CAT_ID_VAL, (const unsigned char*)fqdn_val, ptr.via.array.size * sizeof(uint32_t)); + switch(mpack_table[i].array_index) + { + case MPACK_ARRAY_FQDN_IDS: + fqdn_id_set_cmsg(handler, ptr, i); + break; + case MPACK_ARRAY_SEQ_SIDS: + sids_array_parse_mpack(handler, ptr, i, 1); + break; + case MPACK_ARRAY_ACK_SIDS: + sids_array_parse_mpack(handler, ptr, i, 0); + break; + case MPACK_ARRAY_SEQ_ROUTE_CTX: + route_ctx_parse_mpack(handler, ptr, i, 1); + break; + case MPACK_ARRAY_ACK_ROUTE_CTX: + route_ctx_parse_mpack(handler, ptr, i, 0); + break; + default: + break; } break; default: @@ -117,6 +196,8 @@ int parse_messagepack(const char* data, size_t length, void *ctx) { struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx; size_t off = 0; + msgpack_object *obj = NULL; + msgpack_object *ptr = NULL; msgpack_unpacked unpacked; msgpack_unpacked_init(&unpacked); @@ -124,93 +205,91 @@ int parse_messagepack(const char* data, size_t length, void *ctx) msgpack_unpack_return ret = msgpack_unpack_next(&unpacked, data, length, &off); if (ret != MSGPACK_UNPACK_SUCCESS) { TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: data[%s]", LOG_TAG_CTRLPKT, data); - return -1; + goto end; } - msgpack_object obj = unpacked.data; - if (obj.type != MSGPACK_OBJECT_ARRAY || obj.via.array.size < INDEX_PROXY) { - // TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: msgpack type[%02x], array size:%d", LOG_TAG_CTRLPKT, obj.type, obj.via.array.size); - return -1; + obj = &unpacked.data; + if (obj->type != MSGPACK_OBJECT_ARRAY) { + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: msgpack type is not MSGPACK_OBJECT_ARRAY", LOG_TAG_CTRLPKT); + goto end; } - for (unsigned int i = 0; i < obj.via.array.size; i++) { - msgpack_object ptr = obj.via.array.ptr[i]; + for (unsigned int i = 0; i < obj->via.array.size; i++) { + ptr = &obj->via.array.ptr[i]; switch (i) { case INDEX_TSYNC: - if (ptr.type == MSGPACK_OBJECT_STR) { - memcpy(handler->tsync, ptr.via.str.ptr, ptr.via.str.size); + if (ptr->type == MSGPACK_OBJECT_STR) { + memcpy(handler->tsync, ptr->via.str.ptr, ptr->via.str.size); } else { - TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid tsync type) %02x", LOG_TAG_CTRLPKT, ptr.type); + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid tsync type) %02x", LOG_TAG_CTRLPKT, ptr->type); } break; case INDEX_SESSION_ID: - if (ptr.type == MSGPACK_OBJECT_STR) { - char session_id[64] = {0}; - memcpy(session_id, ptr.via.str.ptr, ptr.via.str.size); - handler->session_id = atoll(session_id); + if (ptr->type == MSGPACK_OBJECT_POSITIVE_INTEGER) { + handler->session_id = ptr->via.u64; } else { - TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid session id type) %02x", LOG_TAG_CTRLPKT, ptr.type); + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid session id type) %02x", LOG_TAG_CTRLPKT, ptr->type); } break; case INDEX_STATE: - if (ptr.type == MSGPACK_OBJECT_STR) { - if (strncasecmp(ptr.via.str.ptr, "opening", ptr.via.str.size) == 0) + if (ptr->type == MSGPACK_OBJECT_STR) { + if (strncasecmp(ptr->via.str.ptr, "opening", ptr->via.str.size) == 0) { handler->state = SESSION_STATE_OPENING; } - else if (strncasecmp(ptr.via.str.ptr, "active", ptr.via.str.size) == 0) + else if (strncasecmp(ptr->via.str.ptr, "active", ptr->via.str.size) == 0) { handler->state = SESSION_STATE_ACTIVE; } - else if (strncasecmp(ptr.via.str.ptr, "closing", ptr.via.str.size) == 0) + else if (strncasecmp(ptr->via.str.ptr, "closing", ptr->via.str.size) == 0) { handler->state = SESSION_STATE_CLOSING; } - else if (strncasecmp(ptr.via.str.ptr, "resetall", ptr.via.str.size) == 0) + else if (strncasecmp(ptr->via.str.ptr, "resetall", ptr->via.str.size) == 0) { handler->state = SESSION_STATE_RESETALL; } else { - TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state value) %s", LOG_TAG_CTRLPKT, ptr.via.str.ptr); + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state value) %s", LOG_TAG_CTRLPKT, ptr->via.str.ptr); } } else { - TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state type) %02x", LOG_TAG_CTRLPKT, ptr.type); + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state type) %02x", LOG_TAG_CTRLPKT, ptr->type); } break; case INDEX_METHOD: - if (ptr.type == MSGPACK_OBJECT_STR) { - memcpy(handler->method, ptr.via.str.ptr, ptr.via.str.size); + if (ptr->type == MSGPACK_OBJECT_STR) { + memcpy(handler->method, ptr->via.str.ptr, ptr->via.str.size); } else { - TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid method type) %02x", LOG_TAG_CTRLPKT, ptr.type); + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid method type) %02x", LOG_TAG_CTRLPKT, ptr->type); } break; - case INDEX_SCE: - if (ptr.type == MSGPACK_OBJECT_ARRAY) { - msgpack_object rule_id = ptr.via.array.ptr[0]; + case INDEX_VALUE_SCE: + if (ptr->type == MSGPACK_OBJECT_ARRAY) { + msgpack_object rule_id = ptr->via.array.ptr[0]; handler->sce_policy_id_num = rule_id.via.array.size; for (uint32_t j = 0; j < rule_id.via.array.size; j++) { handler->sce_policy_ids[j] = rule_id.via.array.ptr[j].via.u64; } } break; - case INDEX_SHAPER: - break; - case INDEX_PROXY: - if (ptr.type == MSGPACK_OBJECT_ARRAY) { + case INDEX_VALUE_PROXY: + if (ptr->type == MSGPACK_OBJECT_ARRAY) { proxy_parse_messagepack(ptr, handler); } else { - TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid proxy type) %02x", LOG_TAG_CTRLPKT, ptr.type); + TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid proxy type) %02x", LOG_TAG_CTRLPKT, ptr->type); } break; default: break; } } +end: + msgpack_unpacked_destroy(&unpacked); return 0; } diff --git a/common/src/tfe_packet_io.cpp b/common/src/tfe_packet_io.cpp index e3fb77b..17ed84b 100644 --- a/common/src/tfe_packet_io.cpp +++ b/common/src/tfe_packet_io.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ #include "tfe_tap_rss.h" #include +#include /* * add: vxlan_hdr * del: marsio_buff_ctrlzone_reset() @@ -46,8 +48,8 @@ #define RX_BURST_MAX 128 #define TRAFFIC_IS_DECRYPTED (1 << 0) -#define SET_TRAFFIC_IS_DECRYPTED(field) (field || TRAFFIC_IS_DECRYPTED) -#define CLEAR_TRAFFIC_IS_DECRYPTED(field) (field && ~TRAFFIC_IS_DECRYPTED) +#define SET_TRAFFIC_IS_DECRYPTED(field) (field | TRAFFIC_IS_DECRYPTED) +#define CLEAR_TRAFFIC_IS_DECRYPTED(field) (field & ~TRAFFIC_IS_DECRYPTED) struct config { @@ -91,850 +93,22 @@ enum inject_pkt_action struct metadata { + int write_ref; uint64_t session_id; char *raw_data; int raw_len; - int dir_is_e2i; + int is_e2i_dir; int is_ctrl_pkt; - uint16_t l7_offset; // only control packet set l7_offset - uint16_t user_field; // only raw packet set traffic_is_decrypted (1 << 0) + uint16_t l7offset; // only control packet set l7offset + uint16_t is_decrypted; struct sids sids; struct route_ctx route_ctx; }; -/****************************************************************************** - * API Declaration - ******************************************************************************/ - -struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_t *coremask); -void packet_io_destory(struct packet_io *handle); - -int packet_io_polling_nf_interface(struct packet_io *handle, int thread_seq, void *ctx); - -extern int tcp_policy_enforce(struct tcp_policy_enforcer *tcp_enforcer, struct tfe_cmsg *cmsg); -extern int tfe_proxy_fds_accept(struct tfe_proxy * ctx, int fd_downstream, int fd_upstream, int fd_fake_c, int fd_fake_s, struct tfe_cmsg * cmsg); - -extern void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id); - -// return 0 : success -// return -1 : error -static int packet_io_config(const char *profile, struct config *config); - -// return 0 : success -// return -1 : error -static int packet_io_get_metadata(marsio_buff_t *tx_buff, struct metadata *meta); -// return 0 : success -// return -1 : error -static int packet_io_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta); -static void packet_io_dump_metadata(marsio_buff_t *tx_buff, struct metadata *meta); - -// return 0 : success -// return -1 : error -static int handle_control_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx); - -static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx, int *action_bytes); - -static int add_ether_header(void *raw_data, char *src_mac, char *dst_mac){ - struct ethhdr *ether_hdr = (struct ethhdr*)raw_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)); - return 0; -} - -// return 0 : success -// return -1 : error -static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); -// return 0 : success -// return -1 : error -static int handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); -// return 0 : success -// return -1 : error -static int handle_session_active(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); -// return 0 : success -// return -1 : error -static int handle_session_resetall(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); - -static void session_value_free_cb(void *ctx); - -// return 0 : not keepalive packet -// return 1 : is keepalive packet -static int is_downstream_keepalive_packet(marsio_buff_t *rx_buff); - - -/****************************************************************************** - * API Definition - ******************************************************************************/ - -struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_t *coremask) -{ - int opt = 1; - struct packet_io *handle = (struct packet_io *)calloc(1, sizeof(struct packet_io)); - assert(handle != NULL); - handle->thread_num = thread_num; - - if (packet_io_config(profile, &(handle->config)) != 0) - { - goto error_out; - } - - handle->instance = marsio_create(); - if (handle->instance == NULL) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to create marsio instance", LOG_TAG_PKTIO); - goto error_out; - } - - if (marsio_option_set(handle->instance, MARSIO_OPT_THREAD_MASK_IN_CPUSET, coremask, sizeof(cpu_set_t)) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set MARSIO_OPT_EXIT_WHEN_ERR option for marsio instance", LOG_TAG_PKTIO); - goto error_out; - } - - if (marsio_option_set(handle->instance, MARSIO_OPT_EXIT_WHEN_ERR, &opt, sizeof(opt)) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set MARSIO_OPT_EXIT_WHEN_ERR option for marsio instance", LOG_TAG_PKTIO); - goto error_out; - } - - if (marsio_init(handle->instance, handle->config.app_symbol) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to initialize marsio instance", LOG_TAG_PKTIO); - goto error_out; - } - - // Netwrok Function Interface - handle->dev_nf_interface.mr_dev = marsio_open_device(handle->instance, handle->config.dev_nf_interface, handle->thread_num, handle->thread_num); - if (handle->dev_nf_interface.mr_dev == NULL) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to open device %s", LOG_TAG_PKTIO, handle->config.dev_nf_interface); - goto error_out; - } - - handle->dev_nf_interface.mr_path = marsio_sendpath_create_by_vdev(handle->dev_nf_interface.mr_dev); - if (handle->dev_nf_interface.mr_path == NULL) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to create sendpath for device %s", LOG_TAG_PKTIO, handle->config.dev_nf_interface); - goto error_out; - } - - return handle; - -error_out: - packet_io_destory(handle); - return NULL; -} - -void packet_io_destory(struct packet_io *handle) -{ - if (handle) - { - if (handle->dev_nf_interface.mr_path) - { - marsio_sendpath_destory(handle->dev_nf_interface.mr_path); - handle->dev_nf_interface.mr_path = NULL; - } - - if (handle->dev_nf_interface.mr_dev) - { - marsio_close_device(handle->dev_nf_interface.mr_dev); - handle->dev_nf_interface.mr_dev = NULL; - } - - if (handle->instance) - { - marsio_destory(handle->instance); - handle->instance = NULL; - } - - free(handle); - handle = NULL; - } -} - -int packet_io_thread_init(struct packet_io *handle, struct acceptor_thread_ctx *thread_ctx) -{ - if (marsio_thread_init(handle->instance) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to init marsio thread %d", LOG_TAG_PKTIO, thread_ctx->thread_index); - return -1; - } - - return 0; -} - -void packet_io_thread_wait(struct packet_io *handle, struct acceptor_thread_ctx *thread_ctx, int timeout_ms) -{ - struct mr_vdev *vdevs[] = {handle->dev_nf_interface.mr_dev}; - - marsio_poll_wait(handle->instance, vdevs, 1, thread_ctx->thread_index, timeout_ms); -} - -// return n_packet_recv -int packet_io_polling_nf_interface(struct packet_io *handle, int thread_seq, void *ctx) -{ - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - - marsio_buff_t *rx_buffs[RX_BURST_MAX]; - - // nr_recv <= rx_burst_max <= RX_BURST_MAX - int nr_recv = marsio_recv_burst(handle->dev_nf_interface.mr_dev, thread_seq, rx_buffs, handle->config.rx_burst_max); - if (nr_recv <= 0) - { - return 0; - } - - for (int j = 0; j < nr_recv; j++) - { - marsio_buff_t *rx_buff = rx_buffs[j]; - int raw_len = marsio_buff_datalen(rx_buff); - - if (is_downstream_keepalive_packet(rx_buff)) - { - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - continue; - } - - if (marsio_buff_is_ctrlbuf(rx_buff)) - { - handle_control_packet(handle, rx_buff, thread_seq, ctx); - throughput_metrics_inc(&g_metrics->ctrl_pkt_rx, 1, raw_len); - // all control packet need bypass - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - } - else - { - int action_bytes = 0; - handle_raw_packet_from_nf(handle, rx_buff, thread_seq, ctx, &action_bytes); - } - } - - return nr_recv; -} - -void handle_decryption_packet_from_tap(const char *data, int len, void *args) -{ - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)args; - struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; - struct packet_io *packet_io = thread->ref_io; - - struct addr_tuple4 inner_addr; - struct raw_pkt_parser raw_parser; - memset(&inner_addr, 0, sizeof(struct addr_tuple4)); - raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); - raw_packet_parser_parse(&raw_parser, (const void *)data, len); - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); - - struct session_node *node = session_table_search_by_addr(thread->session_table, &inner_addr); - if (node == NULL) - { - char *addr_string = addr_tuple4_to_str(&inner_addr); - TFE_LOG_ERROR(g_default_logger, "%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_string); - free(addr_string); - return; - } - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - - marsio_buff_t *tx_buffs[1]; - int alloc_ret = marsio_buff_malloc_device(packet_io->dev_nf_interface.mr_dev, tx_buffs, 1, 0, thread->thread_index); - if (alloc_ret < 0){ - TFE_LOG_ERROR(g_default_logger, "Failed at alloc marsio buffer, ret = %d, thread_seq = %d", - alloc_ret, thread->thread_index); - return; - } - - char *dst = marsio_buff_append(tx_buffs[0], len); - memcpy(dst, data, len); - - struct metadata meta = {0}; - meta.session_id = s_ctx->session_id; - meta.raw_data = dst; - meta.raw_len = len; - meta.user_field = SET_TRAFFIC_IS_DECRYPTED(0); - meta.is_ctrl_pkt = 0; - meta.l7_offset = 0; - meta.sids.num = 1; - meta.sids.elems[0] = acceptor_ctx->sce_sids; - - if (memcmp(&inner_addr, &s_ctx->first_ctrl_pkt.tuple4, sizeof(struct addr_tuple4)) == 0) - meta.dir_is_e2i = s_ctx->first_ctrl_pkt.dir_is_e2i; - else - meta.dir_is_e2i = !s_ctx->first_ctrl_pkt.dir_is_e2i; - - if (meta.dir_is_e2i) - { - route_ctx_copy(&meta.route_ctx, &s_ctx->raw_pkt_e2i_route_ctx); - } - else - { - route_ctx_copy(&meta.route_ctx, &s_ctx->raw_pkt_i2e_route_ctx); - } - packet_io_set_metadata(tx_buffs[0], &meta); - marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread->thread_index, tx_buffs, 1); -} - -void handle_raw_packet_from_tap(const char *data, int len, void *args) -{ - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)args; - struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; - struct packet_io *packet_io = thread->ref_io; - - struct addr_tuple4 inner_addr; - struct raw_pkt_parser raw_parser; - memset(&inner_addr, 0, sizeof(struct addr_tuple4)); - raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); - raw_packet_parser_parse(&raw_parser, (const void *)data, len); - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); - - struct session_node *node = session_table_search_by_addr(thread->session_table, &inner_addr); - if (node == NULL) - { - char *addr_string = addr_tuple4_to_str(&inner_addr); - TFE_LOG_ERROR(g_default_logger, "%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_string); - free(addr_string); - return; - } - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - - marsio_buff_t *tx_buffs[1]; - int alloc_ret = marsio_buff_malloc_device(packet_io->dev_nf_interface.mr_dev, tx_buffs, 1, 0, thread->thread_index); - if (alloc_ret < 0){ - TFE_LOG_ERROR(g_default_logger, "Failed at alloc marsio buffer, ret = %d, thread_seq = %d", - alloc_ret, thread->thread_index); - return; - } - - char *dst = marsio_buff_append(tx_buffs[0], len + s_ctx->first_ctrl_pkt.header_len); - memcpy(dst, s_ctx->first_ctrl_pkt.header_data, s_ctx->first_ctrl_pkt.header_len); - memcpy(dst + s_ctx->first_ctrl_pkt.header_len, data, len); - - struct metadata meta = {0}; - meta.session_id = s_ctx->session_id; - meta.raw_data = dst; - meta.raw_len = len; - meta.user_field = s_ctx->user_field; - meta.is_ctrl_pkt = 0; - meta.l7_offset = 0; - - char *src_mac = NULL; - char *dst_mac = NULL; - if (memcmp(&inner_addr, &s_ctx->first_ctrl_pkt.tuple4, sizeof(struct addr_tuple4)) == 0) { - meta.dir_is_e2i = s_ctx->first_ctrl_pkt.dir_is_e2i; - struct ethhdr *ether_hdr = (struct ethhdr *)(s_ctx->first_ctrl_pkt.header_data); - src_mac = (char *)ether_hdr->h_source; - dst_mac = (char *)ether_hdr->h_dest; - } - else { - meta.dir_is_e2i = !s_ctx->first_ctrl_pkt.dir_is_e2i; - struct ethhdr *ether_hdr = (struct ethhdr *)(s_ctx->first_ctrl_pkt.header_data); - dst_mac = (char *)ether_hdr->h_source; - src_mac = (char *)ether_hdr->h_dest; - } - - if (meta.dir_is_e2i) - { - sids_copy(&meta.sids, &s_ctx->raw_pkt_e2i_sids); - route_ctx_copy(&meta.route_ctx, &s_ctx->raw_pkt_e2i_route_ctx); - } - else - { - sids_copy(&meta.sids, &s_ctx->raw_pkt_i2e_sids); - route_ctx_copy(&meta.route_ctx, &s_ctx->raw_pkt_i2e_route_ctx); - } - packet_io_set_metadata(tx_buffs[0], &meta); - // add_ether_header(dst, src_mac, dst_mac); - marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread->thread_index, tx_buffs, 1); -} - -// return 0 : success -// return -1 : error -static int packet_io_config(const char *profile, struct config *config) -{ - MESA_load_profile_int_def(profile, "PACKET_IO", "rx_burst_max", (int *)&(config->rx_burst_max), 1); - MESA_load_profile_string_nodef(profile, "PACKET_IO", "app_symbol", config->app_symbol, sizeof(config->app_symbol)); - MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_nf_interface", config->dev_nf_interface, sizeof(config->dev_nf_interface)); - - if (config->rx_burst_max > RX_BURST_MAX) - { - TFE_LOG_ERROR(g_default_logger, "%s: invalid rx_burst_max, exceeds limit %d", LOG_TAG_PKTIO, RX_BURST_MAX); - return -1; - } - - if (strlen(config->app_symbol) == 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: invalid app_symbol in %s", LOG_TAG_PKTIO, profile); - return -1; - } - - if (strlen(config->dev_nf_interface) == 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: invalid dev_nf_interface in %s", LOG_TAG_PKTIO, profile); - return -1; - } - - TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->bypass_all_traffic : %d", LOG_TAG_PKTIO, config->bypass_all_traffic); - TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->rx_burst_max : %d", LOG_TAG_PKTIO, config->rx_burst_max); - TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->app_symbol : %s", LOG_TAG_PKTIO, config->app_symbol); - TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->dev_nf_interface : %s", LOG_TAG_PKTIO, config->dev_nf_interface); - - return 0; -} - -// return 0 : success -// return -1 : error -static int packet_io_get_metadata(marsio_buff_t *rx_buff, struct metadata *meta) -{ - memset(meta, 0, sizeof(struct metadata)); - - if (marsio_buff_get_metadata(rx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) <= 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to get session_id from metadata", LOG_TAG_PKTIO); - return -1; - } - - meta->raw_len = marsio_buff_datalen(rx_buff); - meta->raw_data = marsio_buff_mtod(rx_buff); - if (meta->raw_data == NULL || meta->raw_len == 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to get raw_data from metadata", LOG_TAG_PKTIO); - return -1; - } - - // 1: E2I - // 0: I2E - if (marsio_buff_get_metadata(rx_buff, MR_BUFF_DIR, &(meta->dir_is_e2i), sizeof(meta->dir_is_e2i)) <= 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to get buff_dir from metadata", LOG_TAG_PKTIO); - return -1; - } - - if (marsio_buff_is_ctrlbuf(rx_buff)) - { - meta->is_ctrl_pkt = 1; - // only control packet set MR_BUFF_PAYLOAD_OFFSET - if (marsio_buff_get_metadata(rx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7_offset), sizeof(meta->l7_offset)) <= 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to get l7_offset from metadata", LOG_TAG_PKTIO); - return -1; - } - } - else - { - meta->is_ctrl_pkt = 0; - // if (marsio_buff_get_metadata(rx_buff, MR_BUFF_USER_0, &(meta->user_field), sizeof(meta->user_field)) <= 0) - // { - // TFE_LOG_ERROR(g_default_logger, "%s: unable to get user_field from metadata", LOG_TAG_PKTIO); - // return -1; - // } - } - - meta->route_ctx.len = marsio_buff_get_metadata(rx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, sizeof(meta->route_ctx.data)); - if (meta->route_ctx.len <= 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to get route_ctx from metadata", LOG_TAG_PKTIO); - return -1; - } - - meta->sids.num = marsio_buff_get_sid_list(rx_buff, meta->sids.elems, sizeof(meta->sids.elems) / sizeof(meta->sids.elems[0])); - if (meta->sids.num < 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to get sid_list from metadata", LOG_TAG_PKTIO); - return -1; - } - - return 0; -} - -// return 0 : success -// return -1 : error -static int packet_io_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta) -{ - if (meta->session_id) - { - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set session_id for metadata", LOG_TAG_PKTIO); - return -1; - } - } - - // 1: E2I - // 0: I2E -#if 0 - // use MR_BUFF_ROUTE_CTX instead - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_DIR, &(meta->dir_is_e2i), sizeof(meta->dir_is_e2i)) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set buff_dir for metadata", LOG_TAG_PKTIO); - return -1; - } -#endif - - if (meta->is_ctrl_pkt) - { - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7_offset), sizeof(meta->l7_offset)) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set l7_offset for metadata", LOG_TAG_PKTIO); - return -1; - } - } - else - { - // if (marsio_buff_set_metadata(tx_buff, MR_BUFF_USER_0, &(meta->user_field), sizeof(meta->user_field)) != 0) - // { - // TFE_LOG_ERROR(g_default_logger, "%s: unable to set user_field for metadata", LOG_TAG_PKTIO); - // return -1; - // } - } - - if (meta->route_ctx.len > 0) - { - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, meta->route_ctx.len) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set route_ctx for metadata", LOG_TAG_PKTIO); - return -1; - } - } - - if (meta->sids.num > 0) - { - if (marsio_buff_set_sid_list(tx_buff, meta->sids.elems, meta->sids.num) != 0) - { - TFE_LOG_ERROR(g_default_logger, "%s: unable to set sid_list for metadata", LOG_TAG_PKTIO); - return -1; - } - } - - return 0; -} - -static void packet_io_dump_metadata(marsio_buff_t *tx_buff, struct metadata *meta) -{ - TFE_LOG_DEBUG(g_default_logger, "%s: META={session_id: %lu, raw_len: %d, dir_is_e2i: %d, is_ctrl_pkt: %d, l7_offset: %d, user_field: %u, sids_num: %d}", LOG_TAG_PKTIO, meta->session_id, meta->raw_len, meta->dir_is_e2i, meta->is_ctrl_pkt, meta->l7_offset, meta->user_field, meta->sids.num); -} - -static int tcp_restore_set_from_cmsg(struct tfe_cmsg *cmsg, struct tcp_restore_info *restore_info) -{ - int ret = 0; - uint16_t length = 0; - - uint32_t seq; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_SEQ, (unsigned char *)&seq, sizeof(uint32_t), &length); - if (ret == 0) - { - restore_info->client.seq = ntohl(seq); - restore_info->server.ack = ntohl(seq); - } - - uint32_t ack; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_ACK, (unsigned char *)&ack, sizeof(uint32_t), &length); - if (ret == 0) - { - restore_info->client.ack = ntohl(ack); - restore_info->server.seq = ntohl(ack); - } - - uint8_t ts_client; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT, (unsigned char *)&ts_client, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->client.timestamp_perm = !!ts_client; - } - - uint8_t ts_server; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER, (unsigned char *)&ts_server, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->server.timestamp_perm = !!ts_server; - } - - uint32_t ts_client_val; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL, (unsigned char *)&ts_client_val, sizeof(uint32_t), &length); - if (ret == 0) - { - restore_info->client.ts_val = ntohl(ts_client_val); - } - - uint32_t ts_server_val; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL, (unsigned char *)&ts_server_val, sizeof(uint32_t), &length); - if (ret == 0) - { - restore_info->server.ts_val = ntohl(ts_server_val); - } - - uint8_t wsacle_client; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, (unsigned char *)&wsacle_client, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->client.wscale_perm = true; - restore_info->client.wscale = wsacle_client; - } - - uint8_t wsacle_server; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_SERVER, (unsigned char *)&wsacle_server, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->client.wscale_perm = true; - restore_info->client.wscale = wsacle_server; - } - - uint8_t sack_client; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_SACK_CLIENT, (unsigned char *)&sack_client, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->client.sack_perm = !!sack_client; - } - - uint8_t sack_server; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_SACK_SERVER, (unsigned char *)&sack_server, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->server.sack_perm = !!sack_server; - } - - uint16_t mss_client; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_MSS_CLIENT, (unsigned char *)&mss_client, sizeof(uint16_t), &length); - if (ret == 0) - { - restore_info->client.mss = mss_client; - } - - uint16_t mss_server; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_MSS_SERVER, (unsigned char *)&mss_server, sizeof(uint16_t), &length); - if (ret == 0) - { - restore_info->server.mss = mss_server; - } - - uint16_t window_client; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT, (unsigned char *)&window_client, sizeof(uint16_t), &length); - if (ret == 0) - { - restore_info->client.window = window_client; - } - - uint16_t window_server; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WINDOW_SERVER, (unsigned char *)&window_server, sizeof(uint16_t), &length); - if (ret == 0) - { - restore_info->server.window = window_server; - } - - uint8_t packet_cur_dir; - ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR, (unsigned char *)&packet_cur_dir, sizeof(uint8_t), &length); - if (ret == 0) - { - restore_info->cur_dir = (enum tcp_restore_pkt_dir)packet_cur_dir; - } - - return 0; -} - -static int tcp_restore_set_from_pkg(struct addr_tuple4 *tuple4, struct tcp_restore_info *restore_info) -{ - if (tuple4->addr_type == ADDR_TUPLE4_TYPE_V4) - { - struct sockaddr_in *in_addr_client; - struct sockaddr_in *in_addr_server; - - if (restore_info->cur_dir == PKT_DIR_NOT_SET || restore_info->cur_dir == PKT_DIR_C2S) - { - in_addr_client = (struct sockaddr_in *)&restore_info->client.addr; - in_addr_server = (struct sockaddr_in *)&restore_info->server.addr; - } - else - { - in_addr_client = (struct sockaddr_in *)&restore_info->server.addr; - in_addr_server = (struct sockaddr_in *)&restore_info->client.addr; - } - - in_addr_client->sin_family = AF_INET; - in_addr_client->sin_addr = tuple4->addr_v4.src_addr; - in_addr_client->sin_port = tuple4->src_port; - - in_addr_server->sin_family = AF_INET; - in_addr_server->sin_addr = tuple4->addr_v4.dst_addr; - in_addr_server->sin_port = tuple4->dst_port; - } - - if (tuple4->addr_type == ADDR_TUPLE4_TYPE_V6) - { - struct sockaddr_in6 *in6_addr_client; - struct sockaddr_in6 *in6_addr_server; - - if (restore_info->cur_dir == PKT_DIR_NOT_SET || restore_info->cur_dir == PKT_DIR_C2S) - { - in6_addr_client = (struct sockaddr_in6 *)&restore_info->client.addr; - in6_addr_server = (struct sockaddr_in6 *)&restore_info->server.addr; - } - else - { - in6_addr_client = (struct sockaddr_in6 *)&restore_info->server.addr; - in6_addr_server = (struct sockaddr_in6 *)&restore_info->client.addr; - } - - in6_addr_client->sin6_family = AF_INET6; - in6_addr_client->sin6_addr = tuple4->addr_v6.src_addr; - in6_addr_client->sin6_port = tuple4->src_port; - - in6_addr_server->sin6_family = AF_INET6; - in6_addr_server->sin6_addr = tuple4->addr_v6.dst_addr; - in6_addr_server->sin6_port = tuple4->dst_port; - } - - return 0; -} - -// return 0 : success -// return -1 : error -static int handle_control_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx) -{ - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; - struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - - struct metadata meta; - if (packet_io_get_metadata(rx_buff, &meta) == -1) - { - TFE_LOG_ERROR(g_default_logger, "%s: unexpected control packet, unable to get metadata", LOG_TAG_PKTIO); - packet_io_dump_metadata(rx_buff, &meta); - return -1; - } - packet_io_dump_metadata(rx_buff, &meta); - - struct ctrl_pkt_parser ctrl_parser; - ctrl_packet_parser_init(&ctrl_parser); - if (ctrl_packet_parser_parse(&ctrl_parser, meta.raw_data + meta.l7_offset, meta.raw_len - meta.l7_offset) == -1) - { - // TFE_LOG_ERROR(g_default_logger, "%s: unexpected control packet, unable to parse data", LOG_TAG_PKTIO); - return -1; - } - ctrl_packet_parser_dump(&ctrl_parser); - - if (ctrl_parser.session_id != meta.session_id) - { - TFE_LOG_ERROR(g_default_logger, "%s: unexpected control packet, metadata's session %lu != control packet's session %lu", LOG_TAG_PKTIO, meta.session_id, ctrl_parser.session_id); - return -1; - } - - switch (ctrl_parser.state) - { - case SESSION_STATE_OPENING: - __atomic_fetch_add(&g_metrics->ctrl_pkt_opening_num, 1, __ATOMIC_RELAXED); - // when session opening, firewall not send policy id - // return handle_session_opening(&meta, &ctrl_parser, thread_seq, ctx); - break; - case SESSION_STATE_CLOSING: - __atomic_fetch_add(&g_metrics->ctrl_pkt_closing_num, 1, __ATOMIC_RELAXED); - return handle_session_closing(&meta, &ctrl_parser, thread_seq, ctx); - case SESSION_STATE_ACTIVE: - __atomic_fetch_add(&g_metrics->ctrl_pkt_active_num, 1, __ATOMIC_RELAXED); - return handle_session_active(&meta, &ctrl_parser, thread_seq, ctx); - case SESSION_STATE_RESETALL: - __atomic_fetch_add(&g_metrics->ctrl_pkt_resetall_num, 1, __ATOMIC_RELAXED); - return handle_session_resetall(&meta, &ctrl_parser, thread_seq, ctx); - default: - __atomic_fetch_add(&g_metrics->ctrl_pkt_error_num, 1, __ATOMIC_RELAXED); - break; - } - - return 0; -} - -static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx, int *action_bytes) -{ - int nsend = 0; - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; - struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; - struct addr_tuple4 inner_addr; - memset(&inner_addr, 0, sizeof(struct addr_tuple4)); - - int raw_len = marsio_buff_datalen(rx_buff); - char *raw_data = marsio_buff_mtod(rx_buff); - *action_bytes = 0; - - struct metadata meta; - if (packet_io_get_metadata(rx_buff, &meta) == -1) - { - TFE_LOG_ERROR(g_default_logger, "%s: unexpected raw packet, unable to get metadata, bypass !!!", LOG_TAG_PKTIO); - packet_io_dump_metadata(rx_buff, &meta); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - - struct session_node *node = session_table_search_by_id(thread->session_table, meta.session_id); - if (node == NULL) - { - TFE_LOG_ERROR(g_default_logger, "%s: unexpected raw packet, unable to find session %lu from session table, bypass !!!", LOG_TAG_PKTIO, meta.session_id); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - - // update sids - if (meta.dir_is_e2i) - { - sids_write_once(&(s_ctx->raw_pkt_e2i_sids), &(meta.sids)); - if (route_ctx_is_empty(&s_ctx->raw_pkt_e2i_route_ctx)) - { - route_ctx_copy(&s_ctx->raw_pkt_e2i_route_ctx, &meta.route_ctx); - } - } - else - { - sids_write_once(&(s_ctx->raw_pkt_i2e_sids), &(meta.sids)); - if (route_ctx_is_empty(&s_ctx->raw_pkt_i2e_route_ctx)) - { - route_ctx_copy(&s_ctx->raw_pkt_i2e_route_ctx, &meta.route_ctx); - } - } - - struct raw_pkt_parser raw_parser; - raw_packet_parser_init(&raw_parser, meta.session_id, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta.raw_data, meta.raw_len); - - if (meta.user_field && TRAFFIC_IS_DECRYPTED) - { - // c2s - if (memcmp(&inner_addr, &s_ctx->first_ctrl_pkt.tuple4, sizeof(struct addr_tuple4)) == 0) { - add_ether_header(raw_data, acceptor_ctx->config->src_mac, acceptor_ctx->config->tap_s_mac); - if (acceptor_ctx->config->enable_iouring) { - io_uring_submit_write_entry(thread->tap_ctx->io_uring_s, raw_data, raw_len); - } - else { - tfe_tap_write_per_thread(thread->tap_ctx->tap_s, raw_data, raw_len, g_default_logger); - } - } - // s2c - else { - add_ether_header(raw_data, acceptor_ctx->config->src_mac, acceptor_ctx->config->tap_c_mac); - if (acceptor_ctx->config->enable_iouring) { - io_uring_submit_write_entry(thread->tap_ctx->io_uring_c, raw_data, raw_len); - } - else { - tfe_tap_write_per_thread(thread->tap_ctx->tap_c, raw_data, raw_len, g_default_logger); - } - } - } - else - { - add_ether_header(raw_data, acceptor_ctx->config->src_mac, acceptor_ctx->config->tap_mac); - // tap0 - if (acceptor_ctx->config->enable_iouring) { - io_uring_submit_write_entry(thread->tap_ctx->io_uring_fd, raw_data, raw_len); - } - else { - tfe_tap_write_per_thread(thread->tap_ctx->tap_fd, raw_data, raw_len, g_default_logger); - } - } -} - struct tcp_option_mss { uint8_t kind; uint8_t length; @@ -959,6 +133,59 @@ struct tcp_option_time_stamp { uint32_t tsecr; } __attribute__((__packed__)); +extern int tcp_policy_enforce(struct tcp_policy_enforcer *tcp_enforcer, struct tfe_cmsg *cmsg); +extern int tfe_proxy_fds_accept(struct tfe_proxy * ctx, int fd_downstream, int fd_upstream, int fd_fake_c, int fd_fake_s, struct tfe_cmsg * cmsg); +extern void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id); + +/****************************************************************************** + * STATIC + ******************************************************************************/ + +static void time_echo(struct addr_tuple4 inner_addr) +{ + time_t t; + time(&t); + + char *addr_string = addr_tuple4_to_str(&inner_addr); + TFE_LOG_ERROR(g_default_logger, "%s: session:%s, time:%s", LOG_TAG_PKTIO, addr_string, ctime(&t)); + free(addr_string); +} + +// return 0 : not keepalive packet +// return 1 : is keepalive packet +static int is_downstream_keepalive_packet(marsio_buff_t *rx_buff) +{ + int raw_len = marsio_buff_datalen(rx_buff); + char *raw_data = marsio_buff_mtod(rx_buff); + if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr))) + { + return 0; + } + + struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; + if (eth_hdr->h_proto == 0xAAAA) + { + return 1; + } + else + { + return 0; + } +} + +static void session_value_free_cb(void *ctx) +{ + struct session_ctx *s_ctx = (struct session_ctx *)ctx; + session_ctx_free(s_ctx); +} + +static int add_ether_header(void *raw_data, char *src_mac, char *dst_mac){ + struct ethhdr *ether_hdr = (struct ethhdr*)raw_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)); + return 0; +} + static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info) { char buffer[1500] = {0}; @@ -1231,168 +458,370 @@ static int overwrite_tcp_mss(struct tfe_cmsg *cmsg, struct tcp_restore_info *res return 0; } -// return 0 : success -// return -1 : error -static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) +static struct metadata *metadata_new() +{ + struct metadata *meta = (struct metadata *)calloc(1, sizeof(struct metadata)); + + return meta; +} + +static int metadata_is_empty(struct metadata *meta) +{ + return meta->write_ref == 0 ? 1 : 0; +} + +static void metadata_deep_copy(struct metadata *dst, struct metadata *src) +{ + dst->write_ref++; + dst->session_id = src->session_id; + dst->raw_data = (char *)calloc(src->raw_len, sizeof(char)); + memcpy(dst->raw_data, src->raw_data, src->raw_len); + dst->raw_len = src->raw_len; + dst->l7offset = src->l7offset; + dst->is_e2i_dir = src->is_e2i_dir; + dst->is_ctrl_pkt = src->is_ctrl_pkt; + dst->is_decrypted = src->is_decrypted; +} + +static int tcp_restore_set_from_cmsg(struct tfe_cmsg *cmsg, struct tcp_restore_info *restore_info) { - uint8_t *iptmp = NULL; int ret = 0; - int fd_downstream = 0; - int fd_upstream = 0; - int fd_fake_c = 0; - int fd_fake_s = 0; - uint64_t rule_id = 0; - uint16_t size = 0; + uint16_t length = 0; - uint8_t stream_protocol_in_char = 0; - uint8_t enalbe_decrypted_traffic_steering = 0; - struct session_ctx *s_ctx = NULL; - struct addr_tuple4 tuple4; - struct tcp_restore_info restore_info; - memset(&tuple4, 0, sizeof(tuple4)); - memset(&restore_info, 0, sizeof(restore_info)); - - struct sockaddr_in *in_addr_client = (struct sockaddr_in *)&restore_info.client.addr; - struct sockaddr_in *in_addr_server = (struct sockaddr_in *)&restore_info.server.addr; - - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; - struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; - - struct raw_pkt_parser raw_parser; - raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); - if ((char *)payload - meta->raw_data != meta->l7_offset) + uint32_t seq; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_SEQ, (unsigned char *)&seq, sizeof(uint32_t), &length); + if (ret == 0) { - uint16_t offset = (char *)payload - meta->raw_data; - TFE_LOG_ERROR(g_default_logger, "%s: incorrect dataoffset in the control zone of session %lu, offset:%u, l7_offset:%u, payload:%p, raw_data:%p", LOG_TAG_PKTIO, meta->session_id, offset, meta->l7_offset, payload, meta->raw_data); + restore_info->client.seq = ntohl(seq); + restore_info->server.ack = ntohl(seq); } - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &tuple4); - - ret = tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)&rule_id, sizeof(rule_id), &size); - if (ret < 0) - { - TFE_LOG_ERROR(g_default_logger, "failed at fetch rule_id from cmsg: %s", strerror(-ret)); - goto end; - } - - intercept_policy_enforce(thread->ref_proxy->int_ply_enforcer, parser->cmsg); - tcp_policy_enforce(thread->ref_proxy->tcp_ply_enforcer, parser->cmsg); - for (int i = 0; i < parser->sce_policy_id_num; i++) { - chaining_policy_enforce(thread->ref_proxy->chain_ply_enforcer, parser->cmsg, parser->sce_policy_ids[i]); + uint32_t ack; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_ACK, (unsigned char *)&ack, sizeof(uint32_t), &length); + if (ret == 0) + { + restore_info->client.ack = ntohl(ack); + restore_info->server.seq = ntohl(ack); } - tcp_restore_set_from_cmsg(parser->cmsg, &restore_info); - tcp_restore_set_from_pkg(&tuple4, &restore_info); + uint8_t ts_client; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT, (unsigned char *)&ts_client, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->client.timestamp_perm = !!ts_client; + } - if (overwrite_tcp_mss(parser->cmsg, &restore_info)) - { - goto end; - } + uint8_t ts_server; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER, (unsigned char *)&ts_server, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->server.timestamp_perm = !!ts_server; + } - iptmp = (uint8_t *)&in_addr_client->sin_addr.s_addr; - // tcp repair C2S - TFE_LOG_DEBUG(g_default_logger, "restore_info: client"); + uint32_t ts_client_val; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL, (unsigned char *)&ts_client_val, sizeof(uint32_t), &length); + if (ret == 0) + { + restore_info->client.ts_val = ntohl(ts_client_val); + } - TFE_LOG_DEBUG(g_default_logger, "\t addr:%d.%d.%d.%d", iptmp[0], iptmp[1], iptmp[2], iptmp[3]); - TFE_LOG_DEBUG(g_default_logger, "\t port:%u", in_addr_client->sin_port); - TFE_LOG_DEBUG(g_default_logger, "\t seq:%u", restore_info.client.seq); - TFE_LOG_DEBUG(g_default_logger, "\t ack:%u", restore_info.client.ack); - TFE_LOG_DEBUG(g_default_logger, "\t ts_val:%u", restore_info.client.ts_val); - TFE_LOG_DEBUG(g_default_logger, "\t mss:%u", restore_info.client.mss); - TFE_LOG_DEBUG(g_default_logger, "\t window:%u", restore_info.client.window); - TFE_LOG_DEBUG(g_default_logger, "\t wscale:%u", restore_info.client.wscale); - TFE_LOG_DEBUG(g_default_logger, "\t wscale_perm:%s", restore_info.client.wscale_perm > 0?"true":"false"); - TFE_LOG_DEBUG(g_default_logger, "\t timestamp_perm:%s", restore_info.client.timestamp_perm > 0?"true":"false"); - TFE_LOG_DEBUG(g_default_logger, "\t sack_perm:%s", restore_info.client.sack_perm > 0?"true":"false"); + uint32_t ts_server_val; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL, (unsigned char *)&ts_server_val, sizeof(uint32_t), &length); + if (ret == 0) + { + restore_info->server.ts_val = ntohl(ts_server_val); + } + uint8_t wsacle_client; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, (unsigned char *)&wsacle_client, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->client.wscale_perm = true; + restore_info->client.wscale = wsacle_client; + } - iptmp = (uint8_t *)&in_addr_server->sin_addr.s_addr; - // tcp repair C2S - TFE_LOG_DEBUG(g_default_logger, "restore_info: server"); + uint8_t wsacle_server; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WSACLE_SERVER, (unsigned char *)&wsacle_server, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->client.wscale_perm = true; + restore_info->client.wscale = wsacle_server; + } - TFE_LOG_DEBUG(g_default_logger, "\t addr:%d.%d.%d.%d", iptmp[0], iptmp[1], iptmp[2], iptmp[3]); - TFE_LOG_DEBUG(g_default_logger, "\t port:%u", in_addr_server->sin_port); - TFE_LOG_DEBUG(g_default_logger, "\t seq:%u", restore_info.server.seq); - TFE_LOG_DEBUG(g_default_logger, "\t ack:%u", restore_info.server.ack); - TFE_LOG_DEBUG(g_default_logger, "\t ts_val:%u", restore_info.server.ts_val); - TFE_LOG_DEBUG(g_default_logger, "\t mss:%u", restore_info.server.mss); - TFE_LOG_DEBUG(g_default_logger, "\t window:%u", restore_info.server.window); - TFE_LOG_DEBUG(g_default_logger, "\t wscale:%u", restore_info.server.wscale); - TFE_LOG_DEBUG(g_default_logger, "\t wscale_perm:%s", restore_info.server.wscale_perm > 0?"true":"false"); - TFE_LOG_DEBUG(g_default_logger, "\t timestamp_perm:%s", restore_info.server.timestamp_perm > 0?"true":"false"); - TFE_LOG_DEBUG(g_default_logger, "\t sack_perm:%s", restore_info.server.sack_perm > 0?"true":"false"); + uint8_t sack_client; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_SACK_CLIENT, (unsigned char *)&sack_client, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->client.sack_perm = !!sack_client; + } + uint8_t sack_server; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_SACK_SERVER, (unsigned char *)&sack_server, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->server.sack_perm = !!sack_server; + } - fd_upstream = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), thread->ref_tap_config->tap_device, 0x65); - if (fd_upstream < 0) - { - TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(UPSTREAM)"); - goto end; - } + uint16_t mss_client; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_MSS_CLIENT, (unsigned char *)&mss_client, sizeof(uint16_t), &length); + if (ret == 0) + { + restore_info->client.mss = mss_client; + } - // tcp repair S2C - fd_downstream = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), thread->ref_tap_config->tap_device, 0x65); - if (fd_downstream < 0) - { - TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(DOWNSTREAM)"); - goto end; - } + uint16_t mss_server; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_MSS_SERVER, (unsigned char *)&mss_server, sizeof(uint16_t), &length); + if (ret == 0) + { + restore_info->server.mss = mss_server; + } - tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size); - tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering), &size); - if ((STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_http) || - (STREAM_PROTO_SSL == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_ssl) || - enalbe_decrypted_traffic_steering == 1) - { - if (fake_tcp_handshake(thread->ref_proxy, &restore_info) == -1) - { - TFE_LOG_ERROR(g_default_logger, "Failed at fake_tcp_handshake()"); - goto end; - } + uint16_t window_client; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT, (unsigned char *)&window_client, sizeof(uint16_t), &length); + if (ret == 0) + { + restore_info->client.window = window_client; + } - fd_fake_c = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), thread->ref_proxy->traffic_steering_options.device_client, thread->ref_proxy->traffic_steering_options.so_mask_client); - if (fd_fake_c < 0) - { - TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(fd_fake_c)"); - goto end; - } + uint16_t window_server; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_WINDOW_SERVER, (unsigned char *)&window_server, sizeof(uint16_t), &length); + if (ret == 0) + { + restore_info->server.window = window_server; + } - fd_fake_s = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), thread->ref_proxy->traffic_steering_options.device_server, thread->ref_proxy->traffic_steering_options.so_mask_server); - if (fd_fake_s < 0) - { - TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(fd_fake_s)"); - goto end; - } - } - - if (tfe_proxy_fds_accept(thread->ref_proxy, fd_downstream, fd_upstream, fd_fake_c, fd_fake_s, parser->cmsg) < 0) - { - TFE_LOG_ERROR(g_default_logger, "Failed at tfe_proxy_fds_accept()"); - goto end; - } - - s_ctx = session_ctx_new(); - s_ctx->ref_thread_ctx = thread; - s_ctx->session_id = meta->session_id; - s_ctx->cmsg = parser->cmsg; - s_ctx->first_ctrl_pkt.dir_is_e2i = meta->dir_is_e2i; - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &(s_ctx->first_ctrl_pkt.tuple4)); - s_ctx->first_ctrl_pkt.addr_string = addr_tuple4_to_str(&(s_ctx->first_ctrl_pkt.tuple4)); - s_ctx->first_ctrl_pkt.header_data = (char *)calloc(1, meta->l7_offset); - memcpy(s_ctx->first_ctrl_pkt.header_data, meta->raw_data, meta->l7_offset); - s_ctx->first_ctrl_pkt.header_len = meta->l7_offset; - sids_copy(&s_ctx->first_ctrl_pkt.sids, &meta->sids); - route_ctx_copy(&s_ctx->first_ctrl_pkt.route_ctx, &meta->route_ctx); - - TFE_LOG_INFO(g_default_logger, "%s: session %lu %s active first", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - s_ctx->policy_ids = parser->tfe_policy_ids[0]; - - session_table_insert(thread->session_table, s_ctx->session_id, &(s_ctx->first_ctrl_pkt.tuple4), s_ctx, session_value_free_cb); + uint8_t packet_cur_dir; + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR, (unsigned char *)&packet_cur_dir, sizeof(uint8_t), &length); + if (ret == 0) + { + restore_info->cur_dir = (enum tcp_restore_pkt_dir)packet_cur_dir; + } return 0; -end: - return -1; +} + +static int tcp_restore_set_from_pkg(struct addr_tuple4 *tuple4, struct tcp_restore_info *restore_info) +{ + if (tuple4->addr_type == ADDR_TUPLE4_TYPE_V4) + { + struct sockaddr_in *in_addr_client; + struct sockaddr_in *in_addr_server; + + if (restore_info->cur_dir == PKT_DIR_NOT_SET || restore_info->cur_dir == PKT_DIR_C2S) + { + in_addr_client = (struct sockaddr_in *)&restore_info->client.addr; + in_addr_server = (struct sockaddr_in *)&restore_info->server.addr; + } + else + { + in_addr_client = (struct sockaddr_in *)&restore_info->server.addr; + in_addr_server = (struct sockaddr_in *)&restore_info->client.addr; + } + + in_addr_client->sin_family = AF_INET; + in_addr_client->sin_addr = tuple4->addr_v4.src_addr; + in_addr_client->sin_port = tuple4->src_port; + + in_addr_server->sin_family = AF_INET; + in_addr_server->sin_addr = tuple4->addr_v4.dst_addr; + in_addr_server->sin_port = tuple4->dst_port; + } + + if (tuple4->addr_type == ADDR_TUPLE4_TYPE_V6) + { + struct sockaddr_in6 *in6_addr_client; + struct sockaddr_in6 *in6_addr_server; + + if (restore_info->cur_dir == PKT_DIR_NOT_SET || restore_info->cur_dir == PKT_DIR_C2S) + { + in6_addr_client = (struct sockaddr_in6 *)&restore_info->client.addr; + in6_addr_server = (struct sockaddr_in6 *)&restore_info->server.addr; + } + else + { + in6_addr_client = (struct sockaddr_in6 *)&restore_info->server.addr; + in6_addr_server = (struct sockaddr_in6 *)&restore_info->client.addr; + } + + in6_addr_client->sin6_family = AF_INET6; + in6_addr_client->sin6_addr = tuple4->addr_v6.src_addr; + in6_addr_client->sin6_port = tuple4->src_port; + + in6_addr_server->sin6_family = AF_INET6; + in6_addr_server->sin6_addr = tuple4->addr_v6.dst_addr; + in6_addr_server->sin6_port = tuple4->dst_port; + } + + return 0; +} + +// return 0 : success +// return -1 : error +static int packet_io_config(const char *profile, struct config *config) +{ + MESA_load_profile_int_def(profile, "PACKET_IO", "rx_burst_max", (int *)&(config->rx_burst_max), 1); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "app_symbol", config->app_symbol, sizeof(config->app_symbol)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_nf_interface", config->dev_nf_interface, sizeof(config->dev_nf_interface)); + + if (config->rx_burst_max > RX_BURST_MAX) + { + TFE_LOG_ERROR(g_default_logger, "%s: invalid rx_burst_max, exceeds limit %d", LOG_TAG_PKTIO, RX_BURST_MAX); + return -1; + } + + if (strlen(config->app_symbol) == 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: invalid app_symbol in %s", LOG_TAG_PKTIO, profile); + return -1; + } + + if (strlen(config->dev_nf_interface) == 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: invalid dev_nf_interface in %s", LOG_TAG_PKTIO, profile); + return -1; + } + + TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->bypass_all_traffic : %d", LOG_TAG_PKTIO, config->bypass_all_traffic); + TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->rx_burst_max : %d", LOG_TAG_PKTIO, config->rx_burst_max); + TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->app_symbol : %s", LOG_TAG_PKTIO, config->app_symbol); + TFE_LOG_DEBUG(g_default_logger, "%s: PACKET_IO->dev_nf_interface : %s", LOG_TAG_PKTIO, config->dev_nf_interface); + + return 0; +} + +// return 0 : success +// return -1 : error +static int packet_io_get_metadata(marsio_buff_t *rx_buff, struct metadata *meta) +{ + memset(meta, 0, sizeof(struct metadata)); + + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) <= 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get session_id from metadata", LOG_TAG_PKTIO); + return -1; + } + + meta->raw_len = marsio_buff_datalen(rx_buff); + meta->raw_data = marsio_buff_mtod(rx_buff); + if (meta->raw_data == NULL || meta->raw_len == 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get raw_data from metadata", LOG_TAG_PKTIO); + return -1; + } + + // 1: E2I + // 0: I2E + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_DIR, &(meta->is_e2i_dir), sizeof(meta->is_e2i_dir)) <= 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get buff_dir from metadata", LOG_TAG_PKTIO); + return -1; + } + + if (marsio_buff_is_ctrlbuf(rx_buff)) + { + meta->is_ctrl_pkt = 1; + // only control packet set MR_BUFF_PAYLOAD_OFFSET + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7offset), sizeof(meta->l7offset)) <= 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get l7offset from metadata", LOG_TAG_PKTIO); + return -1; + } + } + else + { + meta->is_ctrl_pkt = 0; + uint16_t user_data = 0; + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_USER_0, &(user_data), sizeof(user_data)) <= 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get is_decrypted from metadata", LOG_TAG_PKTIO); + return -1; + } + if (user_data & TRAFFIC_IS_DECRYPTED) + { + meta->is_decrypted = 1; + } + else + { + meta->is_decrypted = 0; + } + } + + meta->route_ctx.len = marsio_buff_get_metadata(rx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, sizeof(meta->route_ctx.data)); + if (meta->route_ctx.len <= 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get route_ctx from metadata", LOG_TAG_PKTIO); + return -1; + } + + meta->sids.num = marsio_buff_get_sid_list(rx_buff, meta->sids.elems, sizeof(meta->sids.elems) / sizeof(meta->sids.elems[0])); + if (meta->sids.num < 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to get sid_list from metadata", LOG_TAG_PKTIO); + return -1; + } + + return 0; +} + +// return 0 : success +// return -1 : error +static int packet_io_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta) +{ + if (meta->session_id) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set session_id for metadata", LOG_TAG_PKTIO); + return -1; + } + } + + if (meta->is_ctrl_pkt) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7offset), sizeof(meta->l7offset)) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set l7offset for metadata", LOG_TAG_PKTIO); + return -1; + } + } + else + { + uint16_t user_data = 0; + if (meta->is_decrypted) + { + user_data = SET_TRAFFIC_IS_DECRYPTED(user_data); + } + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_USER_0, &(user_data), sizeof(user_data)) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set is_decrypted for metadata", LOG_TAG_PKTIO); + return -1; + } + } + + if (meta->route_ctx.len > 0) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, meta->route_ctx.len) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set route_ctx for metadata", LOG_TAG_PKTIO); + return -1; + } + } + + if (meta->sids.num > 0) + { + if (marsio_buff_set_sid_list(tx_buff, meta->sids.elems, meta->sids.num) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set sid_list for metadata", LOG_TAG_PKTIO); + return -1; + } + } + + return 0; +} + +static void packet_io_dump_metadata(marsio_buff_t *tx_buff, struct metadata *meta) +{ + TFE_LOG_DEBUG(g_default_logger, "%s: META={session_id: %lu, raw_len: %d, is_e2i_dir: %d, is_ctrl_pkt: %d, l7offset: %d, is_decrypted: %u, sids_num: %d}", LOG_TAG_PKTIO, meta->session_id, meta->raw_len, meta->is_e2i_dir, meta->is_ctrl_pkt, meta->l7offset, meta->is_decrypted, meta->sids.num); } /* @@ -1419,41 +848,210 @@ static void send_event_log(struct session_ctx *s_ctx, int thread_seq, void *ctx) struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; struct packet_io *packet_io = thread->ref_io; - char buffer[32] = {0}; - sprintf(buffer, "%lu", s_ctx->session_id); + return; +} - cJSON *root = cJSON_CreateObject(); - cJSON_AddStringToObject(root, "tsync", "1.0"); - cJSON_AddStringToObject(root, "session_id", buffer); - cJSON_AddStringToObject(root, "state", "closing"); - cJSON_AddStringToObject(root, "method", "log_update"); - cJSON *sf_profile_ids = cJSON_CreateArray(); +// return 0 : success +// return -1 : error +static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) +{ + uint8_t *iptmp = NULL; + int ret = 0; + int fd_downstream = 0; + int fd_upstream = 0; + int fd_fake_c = 0; + int fd_fake_s = 0; + uint64_t rule_id = 0; + uint16_t size = 0; + char *addr_str = NULL; - cJSON *params = cJSON_CreateObject(); - cJSON_AddItemToObject(params, "sf_profile_ids", sf_profile_ids); - cJSON_AddItemToObject(root, "params", params); - char *json_str = cJSON_PrintUnformatted(root); + uint8_t stream_protocol_in_char = 0; + uint8_t enalbe_decrypted_traffic_steering = 0; + struct ethhdr *ether_hdr = NULL; + struct session_ctx *s_ctx = NULL; + struct addr_tuple4 inner_tuple4; + struct tcp_restore_info restore_info; + memset(&inner_tuple4, 0, sizeof(inner_tuple4)); + memset(&restore_info, 0, sizeof(restore_info)); - TFE_LOG_INFO(g_default_logger, "%s: session %lu %s event log: %s", LOG_TAG_METRICS, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string, json_str); + struct sockaddr_in *in_addr_client = (struct sockaddr_in *)&restore_info.client.addr; + struct sockaddr_in *in_addr_server = (struct sockaddr_in *)&restore_info.server.addr; - marsio_buff_t *tx_buffs[1]; - marsio_buff_malloc_device(packet_io->dev_nf_interface.mr_dev, tx_buffs, 1, 0, thread_seq); - char *dst = marsio_buff_append(tx_buffs[0], s_ctx->first_ctrl_pkt.header_len + strlen(json_str)); - memcpy(dst, s_ctx->first_ctrl_pkt.header_data, s_ctx->first_ctrl_pkt.header_len); - memcpy(dst + s_ctx->first_ctrl_pkt.header_len, json_str, strlen(json_str)); + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; + struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; - struct metadata meta = {0}; - meta.session_id = s_ctx->session_id; - meta.is_ctrl_pkt = 1; - meta.l7_offset = s_ctx->first_ctrl_pkt.header_len; - meta.sids.num = 1; - meta.sids.elems[0] = acceptor_ctx->firewall_sids; - route_ctx_copy(&meta.route_ctx, &s_ctx->first_ctrl_pkt.route_ctx); - packet_io_set_metadata(tx_buffs[0], &meta); - marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread_seq, tx_buffs, 1); + struct raw_pkt_parser raw_parser; + raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); + const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); + if ((char *)payload - meta->raw_data != meta->l7offset) + { + uint16_t offset = (char *)payload - meta->raw_data; + TFE_LOG_ERROR(g_default_logger, "%s: incorrect dataoffset in the control zone of session %lu, offset:%u, l7offset:%u, payload:%p, raw_data:%p", LOG_TAG_PKTIO, meta->session_id, offset, meta->l7offset, payload, meta->raw_data); + } - free(json_str); - cJSON_Delete(root); + raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_tuple4); + + intercept_policy_enforce(thread->ref_proxy->int_ply_enforcer, parser->cmsg); + tcp_policy_enforce(thread->ref_proxy->tcp_ply_enforcer, parser->cmsg); + for (int i = 0; i < parser->sce_policy_id_num; i++) { + chaining_policy_enforce(thread->ref_proxy->chain_ply_enforcer, parser->cmsg, parser->sce_policy_ids[i]); + } + + tcp_restore_set_from_cmsg(parser->cmsg, &restore_info); + tcp_restore_set_from_pkg(&inner_tuple4, &restore_info); + + if (overwrite_tcp_mss(parser->cmsg, &restore_info)) + { + goto end; + } + + iptmp = (uint8_t *)&in_addr_client->sin_addr.s_addr; + // tcp repair C2S + addr_str = addr_tuple4_to_str(&inner_tuple4); + TFE_LOG_DEBUG(g_default_logger, "restore_info session %lu %s : client", meta->session_id, addr_str); + + TFE_LOG_DEBUG(g_default_logger, "\t addr:%d.%d.%d.%d", iptmp[0], iptmp[1], iptmp[2], iptmp[3]); + TFE_LOG_DEBUG(g_default_logger, "\t port:%u", in_addr_client->sin_port); + TFE_LOG_DEBUG(g_default_logger, "\t seq:%u", restore_info.client.seq); + TFE_LOG_DEBUG(g_default_logger, "\t ack:%u", restore_info.client.ack); + TFE_LOG_DEBUG(g_default_logger, "\t ts_val:%u", restore_info.client.ts_val); + TFE_LOG_DEBUG(g_default_logger, "\t mss:%u", restore_info.client.mss); + TFE_LOG_DEBUG(g_default_logger, "\t window:%u", restore_info.client.window); + TFE_LOG_DEBUG(g_default_logger, "\t wscale:%u", restore_info.client.wscale); + TFE_LOG_DEBUG(g_default_logger, "\t wscale_perm:%s", restore_info.client.wscale_perm > 0?"true":"false"); + TFE_LOG_DEBUG(g_default_logger, "\t timestamp_perm:%s", restore_info.client.timestamp_perm > 0?"true":"false"); + TFE_LOG_DEBUG(g_default_logger, "\t sack_perm:%s", restore_info.client.sack_perm > 0?"true":"false"); + + + iptmp = (uint8_t *)&in_addr_server->sin_addr.s_addr; + // tcp repair C2S + TFE_LOG_DEBUG(g_default_logger, "restore_info session %lu %s : server", meta->session_id, addr_str); + + TFE_LOG_DEBUG(g_default_logger, "\t addr:%d.%d.%d.%d", iptmp[0], iptmp[1], iptmp[2], iptmp[3]); + TFE_LOG_DEBUG(g_default_logger, "\t port:%u", in_addr_server->sin_port); + TFE_LOG_DEBUG(g_default_logger, "\t seq:%u", restore_info.server.seq); + TFE_LOG_DEBUG(g_default_logger, "\t ack:%u", restore_info.server.ack); + TFE_LOG_DEBUG(g_default_logger, "\t ts_val:%u", restore_info.server.ts_val); + TFE_LOG_DEBUG(g_default_logger, "\t mss:%u", restore_info.server.mss); + TFE_LOG_DEBUG(g_default_logger, "\t window:%u", restore_info.server.window); + TFE_LOG_DEBUG(g_default_logger, "\t wscale:%u", restore_info.server.wscale); + TFE_LOG_DEBUG(g_default_logger, "\t wscale_perm:%s", restore_info.server.wscale_perm > 0?"true":"false"); + TFE_LOG_DEBUG(g_default_logger, "\t timestamp_perm:%s", restore_info.server.timestamp_perm > 0?"true":"false"); + TFE_LOG_DEBUG(g_default_logger, "\t sack_perm:%s", restore_info.server.sack_perm > 0?"true":"false"); + + free(addr_str); + + fd_upstream = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), thread->ref_tap_config->tap_device, 0x65); + if (fd_upstream < 0) + { + TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(UPSTREAM)"); + goto end; + } + + // tcp repair S2C + fd_downstream = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), thread->ref_tap_config->tap_device, 0x65); + if (fd_downstream < 0) + { + TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(DOWNSTREAM)"); + goto end; + } + + tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size); + tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering), &size); + if ((STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_http) || + (STREAM_PROTO_SSL == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_ssl) || + enalbe_decrypted_traffic_steering == 1) + { + if (fake_tcp_handshake(thread->ref_proxy, &restore_info) == -1) + { + TFE_LOG_ERROR(g_default_logger, "session %lu Failed at fake_tcp_handshake()", meta->session_id); + goto end; + } + + fd_fake_c = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), thread->ref_proxy->traffic_steering_options.device_client, thread->ref_proxy->traffic_steering_options.so_mask_client); + if (fd_fake_c < 0) + { + TFE_LOG_ERROR(g_default_logger, "session %lu Failed at tcp_restore_fd_create(fd_fake_c)", meta->session_id); + goto end; + } + + fd_fake_s = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), thread->ref_proxy->traffic_steering_options.device_server, thread->ref_proxy->traffic_steering_options.so_mask_server); + if (fd_fake_s < 0) + { + TFE_LOG_ERROR(g_default_logger, "session %lu Failed at tcp_restore_fd_create(fd_fake_s)", meta->session_id); + goto end; + } + } + + if (tfe_proxy_fds_accept(thread->ref_proxy, fd_downstream, fd_upstream, fd_fake_c, fd_fake_s, parser->cmsg) < 0) + { + TFE_LOG_ERROR(g_default_logger, "session %lu Failed at tfe_proxy_fds_accept()", meta->session_id); + goto end; + } + + s_ctx = session_ctx_new(); + s_ctx->raw_meta_i2e = metadata_new(); + s_ctx->raw_meta_e2i = metadata_new(); + s_ctx->ctrl_meta = metadata_new(); + + s_ctx->ref_thread_ctx = thread; + s_ctx->session_id = meta->session_id; + s_ctx->session_addr = addr_tuple4_to_str(&inner_tuple4); + s_ctx->cmsg = parser->cmsg; + metadata_deep_copy(s_ctx->ctrl_meta, meta); + + ether_hdr = (struct ethhdr *)(s_ctx->ctrl_meta->raw_data); + memcpy(s_ctx->client_mac, ether_hdr->h_source, 6); + memcpy(s_ctx->server_mac, ether_hdr->h_dest, 6); + + // c2s + s_ctx->c2s_info.is_e2i_dir = meta->is_e2i_dir; + s_ctx->c2s_info.tuple4 = inner_tuple4; + + // s2c + s_ctx->s2c_info.is_e2i_dir = !meta->is_e2i_dir; + addr_tuple4_reverse(&inner_tuple4, &s_ctx->s2c_info.tuple4); + + s_ctx->policy_ids = parser->tfe_policy_ids[0]; + + sids_copy(&s_ctx->ctrl_meta->sids, &meta->sids); + route_ctx_copy(&s_ctx->ctrl_meta->route_ctx, &meta->route_ctx); + if (s_ctx->c2s_info.is_e2i_dir) { + sids_copy(&s_ctx->raw_meta_e2i->sids, &parser->seq_sids); + route_ctx_copy(&s_ctx->raw_meta_e2i->route_ctx, &parser->seq_route_ctx); + sids_copy(&s_ctx->raw_meta_i2e->sids, &parser->ack_sids); + route_ctx_copy(&s_ctx->raw_meta_i2e->route_ctx, &parser->ack_route_ctx); + } + else + { + sids_copy(&s_ctx->raw_meta_i2e->sids, &parser->seq_sids); + route_ctx_copy(&s_ctx->raw_meta_i2e->route_ctx, &parser->seq_route_ctx); + sids_copy(&s_ctx->raw_meta_e2i->sids, &parser->ack_sids); + route_ctx_copy(&s_ctx->raw_meta_e2i->route_ctx, &parser->ack_route_ctx); + } + + TFE_LOG_INFO(g_default_logger, "%s: session %lu %s active first", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->session_addr); + + session_table_insert(thread->session_table, s_ctx->session_id, &(s_ctx->c2s_info.tuple4), s_ctx, session_value_free_cb); + + return 0; +end: + return -1; +} + +// return 0 : success +// return -1 : error +static int handle_session_active(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) +{ + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; + + struct session_node *node = session_table_search_by_id(thread->session_table, meta->session_id); + if (!node) + { + return handle_session_opening(meta, parser, thread_seq, ctx); + } + + return 0; } // return 0 : success @@ -1466,7 +1064,7 @@ static int handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser if (node) { struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - TFE_LOG_INFO(g_default_logger, "%s: session %lu %s closing", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); + TFE_LOG_INFO(g_default_logger, "%s: session %lu closing", LOG_TAG_PKTIO, s_ctx->session_id); send_event_log(s_ctx, thread_seq, ctx); @@ -1477,35 +1075,6 @@ static int handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser return -1; } -// return 0 : success -// return -1 : error -static int handle_session_active(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) -{ - struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; - - struct session_node *node = session_table_search_by_id(thread->session_table, meta->session_id); - if (node) - { - struct raw_pkt_parser raw_parser; - raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); - if ((char *)payload - (char *)&meta->raw_data != meta->l7_offset) - { - TFE_LOG_ERROR(g_default_logger, "%s: incorrect dataoffset in the control zone of session %lu", LOG_TAG_PKTIO, meta->session_id); - } - - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - TFE_LOG_INFO(g_default_logger, "%s: session %lu %s active again", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - s_ctx->policy_ids = parser->tfe_policy_ids[0]; - } - else - { - return handle_session_opening(meta, parser, thread_seq, ctx); - } - - return 0; -} - // return 0 : success // return -1 : error static int handle_session_resetall(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) @@ -1524,30 +1093,439 @@ static int handle_session_resetall(struct metadata *meta, struct ctrl_pkt_parser return 0; } -static void session_value_free_cb(void *ctx) +// return 0 : success +// return -1 : error +static int handle_control_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx) { - struct session_ctx *s_ctx = (struct session_ctx *)ctx; - session_ctx_free(s_ctx); -} + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; + struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; + struct global_metrics *g_metrics = thread->ref_metrics; -// return 0 : not keepalive packet -// return 1 : is keepalive packet -static int is_downstream_keepalive_packet(marsio_buff_t *rx_buff) -{ - int raw_len = marsio_buff_datalen(rx_buff); - char *raw_data = marsio_buff_mtod(rx_buff); - if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr))) + struct metadata meta; + if (packet_io_get_metadata(rx_buff, &meta) == -1) { - return 0; + TFE_LOG_ERROR(g_default_logger, "%s: unexpected control packet, unable to get metadata", LOG_TAG_PKTIO); + packet_io_dump_metadata(rx_buff, &meta); + return -1; } - struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; - if (eth_hdr->h_proto == 0xAAAA) + struct ctrl_pkt_parser ctrl_parser; + ctrl_packet_parser_init(&ctrl_parser); + if (ctrl_packet_parser_parse(&ctrl_parser, meta.raw_data + meta.l7offset, meta.raw_len - meta.l7offset) == -1) { - return 1; + TFE_LOG_ERROR(g_default_logger, "%s: unexpected control packet, unable to parse data", LOG_TAG_PKTIO); + return -1; + } + ctrl_packet_parser_dump(&ctrl_parser); + + if (ctrl_parser.session_id != meta.session_id) + { + TFE_LOG_ERROR(g_default_logger, "%s: unexpected control packet, metadata's session %lu != control packet's session %lu", LOG_TAG_PKTIO, meta.session_id, ctrl_parser.session_id); + return -1; + } + + switch (ctrl_parser.state) + { + case SESSION_STATE_OPENING: + __atomic_fetch_add(&g_metrics->ctrl_pkt_opening_num, 1, __ATOMIC_RELAXED); + // when session opening, firewall not send policy id + // return handle_session_opening(&meta, &ctrl_parser, thread_seq, ctx); + break; + case SESSION_STATE_CLOSING: + __atomic_fetch_add(&g_metrics->ctrl_pkt_closing_num, 1, __ATOMIC_RELAXED); + return handle_session_closing(&meta, &ctrl_parser, thread_seq, ctx); + case SESSION_STATE_ACTIVE: + __atomic_fetch_add(&g_metrics->ctrl_pkt_active_num, 1, __ATOMIC_RELAXED); + return handle_session_active(&meta, &ctrl_parser, thread_seq, ctx); + case SESSION_STATE_RESETALL: + __atomic_fetch_add(&g_metrics->ctrl_pkt_resetall_num, 1, __ATOMIC_RELAXED); + return handle_session_resetall(&meta, &ctrl_parser, thread_seq, ctx); + default: + __atomic_fetch_add(&g_metrics->ctrl_pkt_error_num, 1, __ATOMIC_RELAXED); + break; + } + + return 0; +} + +static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx) +{ + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; + struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; + struct global_metrics *g_metrics = thread->ref_metrics; + struct addr_tuple4 inner_addr; + memset(&inner_addr, 0, sizeof(struct addr_tuple4)); + + int raw_len = marsio_buff_datalen(rx_buff); + char *raw_data = marsio_buff_mtod(rx_buff); + char *buff = NULL; + int buff_size = 0; + + struct metadata meta; + if (packet_io_get_metadata(rx_buff, &meta) == -1) + { + TFE_LOG_ERROR(g_default_logger, "%s: unexpected raw packet, unable to get metadata, bypass !!!", LOG_TAG_PKTIO); + packet_io_dump_metadata(rx_buff, &meta); + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + return -1; + } + + struct session_node *node = session_table_search_by_id(thread->session_table, meta.session_id); + if (node == NULL) + { + TFE_LOG_ERROR(g_default_logger, "%s: unexpected raw packet, unable to find session %lu from session table, bypass !!!", LOG_TAG_PKTIO, meta.session_id); + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + return -1; + } + + struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; + + if (meta.is_e2i_dir) + { + if (metadata_is_empty(s_ctx->raw_meta_e2i)) + { + metadata_deep_copy(s_ctx->raw_meta_e2i, &meta); + } } else { - return 0; + if (metadata_is_empty(s_ctx->raw_meta_i2e)) + { + metadata_deep_copy(s_ctx->raw_meta_i2e, &meta); + } + } + + if (meta.is_decrypted) + { + // c2s + if (meta.is_e2i_dir == s_ctx->c2s_info.is_e2i_dir) { + add_ether_header(raw_data, acceptor_ctx->config->src_mac, acceptor_ctx->config->tap_s_mac); + if (acceptor_ctx->config->enable_iouring) { + io_uring_submit_write_entry(thread->tap_ctx->io_uring_s, raw_data, raw_len); + } + else { + tfe_tap_write_per_thread(thread->tap_ctx->tap_s, raw_data, raw_len, g_default_logger); + } + throughput_metrics_inc(&g_metrics->tap_s_pkt_tx, 1, raw_len); + } + // s2c + else { + add_ether_header(raw_data, acceptor_ctx->config->src_mac, acceptor_ctx->config->tap_c_mac); + if (acceptor_ctx->config->enable_iouring) { + io_uring_submit_write_entry(thread->tap_ctx->io_uring_c, raw_data, raw_len); + } + else { + tfe_tap_write_per_thread(thread->tap_ctx->tap_c, raw_data, raw_len, g_default_logger); + } + throughput_metrics_inc(&g_metrics->tap_c_pkt_tx, 1, raw_len); + } + } + else + { +#if 0 + struct raw_pkt_parser raw_parser; + raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); + const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); + buff_size = raw_len - ((char *)payload - meta->raw_data) + sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct tcphdr); +#endif + // send to tap0 + add_ether_header(raw_data, acceptor_ctx->config->src_mac, acceptor_ctx->config->tap_mac); + if (acceptor_ctx->config->enable_iouring) { + io_uring_submit_write_entry(thread->tap_ctx->io_uring_fd, raw_data, raw_len); + } + else { + tfe_tap_write_per_thread(thread->tap_ctx->tap_fd, raw_data, raw_len, g_default_logger); + } + throughput_metrics_inc(&g_metrics->tap_pkt_tx, 1, raw_len); + } + marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); + return 0; +} + + +/****************************************************************************** + * EXTERN + ******************************************************************************/ + +int packet_io_thread_init(struct packet_io *handle, struct acceptor_thread_ctx *thread_ctx) +{ + if (marsio_thread_init(handle->instance) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to init marsio thread %d", LOG_TAG_PKTIO, thread_ctx->thread_index); + return -1; + } + + return 0; +} + +void packet_io_thread_wait(struct packet_io *handle, struct acceptor_thread_ctx *thread_ctx, int timeout_ms) +{ + struct mr_vdev *vdevs[] = {handle->dev_nf_interface.mr_dev}; + + marsio_poll_wait(handle->instance, vdevs, 1, thread_ctx->thread_index, timeout_ms); +} + +void packet_io_destory(struct packet_io *handle) +{ + if (handle) + { + if (handle->dev_nf_interface.mr_path) + { + marsio_sendpath_destory(handle->dev_nf_interface.mr_path); + handle->dev_nf_interface.mr_path = NULL; + } + + if (handle->dev_nf_interface.mr_dev) + { + marsio_close_device(handle->dev_nf_interface.mr_dev); + handle->dev_nf_interface.mr_dev = NULL; + } + + if (handle->instance) + { + marsio_destory(handle->instance); + handle->instance = NULL; + } + + free(handle); + handle = NULL; } } + +struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_t *coremask) +{ + int opt = 1; + struct packet_io *handle = (struct packet_io *)calloc(1, sizeof(struct packet_io)); + assert(handle != NULL); + handle->thread_num = thread_num; + + if (packet_io_config(profile, &(handle->config)) != 0) + { + goto error_out; + } + + handle->instance = marsio_create(); + if (handle->instance == NULL) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to create marsio instance", LOG_TAG_PKTIO); + goto error_out; + } + + if (marsio_option_set(handle->instance, MARSIO_OPT_THREAD_MASK_IN_CPUSET, coremask, sizeof(cpu_set_t)) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set MARSIO_OPT_EXIT_WHEN_ERR option for marsio instance", LOG_TAG_PKTIO); + goto error_out; + } + + if (marsio_option_set(handle->instance, MARSIO_OPT_EXIT_WHEN_ERR, &opt, sizeof(opt)) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to set MARSIO_OPT_EXIT_WHEN_ERR option for marsio instance", LOG_TAG_PKTIO); + goto error_out; + } + + if (marsio_init(handle->instance, handle->config.app_symbol) != 0) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to initialize marsio instance", LOG_TAG_PKTIO); + goto error_out; + } + + // Netwrok Function Interface + handle->dev_nf_interface.mr_dev = marsio_open_device(handle->instance, handle->config.dev_nf_interface, handle->thread_num, handle->thread_num); + if (handle->dev_nf_interface.mr_dev == NULL) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to open device %s", LOG_TAG_PKTIO, handle->config.dev_nf_interface); + goto error_out; + } + + handle->dev_nf_interface.mr_path = marsio_sendpath_create_by_vdev(handle->dev_nf_interface.mr_dev); + if (handle->dev_nf_interface.mr_path == NULL) + { + TFE_LOG_ERROR(g_default_logger, "%s: unable to create sendpath for device %s", LOG_TAG_PKTIO, handle->config.dev_nf_interface); + goto error_out; + } + + return handle; + +error_out: + packet_io_destory(handle); + return NULL; +} + +// return n_packet_recv +int packet_io_polling_nf_interface(struct packet_io *handle, int thread_seq, void *ctx) +{ + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)ctx; + struct global_metrics *g_metrics = thread->ref_metrics; + + marsio_buff_t *rx_buffs[RX_BURST_MAX]; + + // nr_recv <= rx_burst_max <= RX_BURST_MAX + int nr_recv = marsio_recv_burst(handle->dev_nf_interface.mr_dev, thread_seq, rx_buffs, handle->config.rx_burst_max); + if (nr_recv <= 0) + { + return 0; + } + + for (int j = 0; j < nr_recv; j++) + { + marsio_buff_t *rx_buff = rx_buffs[j]; + int raw_len = marsio_buff_datalen(rx_buff); + + if (is_downstream_keepalive_packet(rx_buff)) + { + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + continue; + } + + if (marsio_buff_is_ctrlbuf(rx_buff)) + { + throughput_metrics_inc(&g_metrics->ctrl_pkt_rx, 1, raw_len); + // all control packet need bypass + handle_control_packet(handle, rx_buff, thread_seq, ctx); + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + } + else + { + throughput_metrics_inc(&g_metrics->raw_pkt_rx, 1, raw_len); + handle_raw_packet_from_nf(handle, rx_buff, thread_seq, ctx); + } + } + + return nr_recv; +} + +void handle_decryption_packet_from_tap(const char *data, int len, void *args) +{ + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)args; + struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; + struct packet_io *packet_io = thread->ref_io; + + struct addr_tuple4 inner_addr; + struct raw_pkt_parser raw_parser; + memset(&inner_addr, 0, sizeof(struct addr_tuple4)); + raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); + raw_packet_parser_parse(&raw_parser, (const void *)data, len); + raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); + + struct session_node *node = session_table_search_by_addr(thread->session_table, &inner_addr); + if (node == NULL) + { + char *addr_string = addr_tuple4_to_str(&inner_addr); + TFE_LOG_ERROR(g_default_logger, "%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_string); + free(addr_string); + return; + } + struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; + + marsio_buff_t *tx_buffs[1]; + int alloc_ret = marsio_buff_malloc_device(packet_io->dev_nf_interface.mr_dev, tx_buffs, 1, 0, thread->thread_index); + if (alloc_ret < 0){ + TFE_LOG_ERROR(g_default_logger, "Failed at alloc marsio buffer, ret = %d, thread_seq = %d", + alloc_ret, thread->thread_index); + return; + } + + char *dst = marsio_buff_append(tx_buffs[0], len); + memcpy(dst, data, len); + + struct metadata meta = {0}; + meta.session_id = s_ctx->session_id; + meta.raw_data = dst; + meta.raw_len = len; + meta.is_decrypted = SET_TRAFFIC_IS_DECRYPTED(0); + meta.is_ctrl_pkt = 0; + meta.l7offset = 0; + meta.sids.num = 1; + meta.sids.elems[0] = acceptor_ctx->sce_sids; + + if (memcmp(&inner_addr, &s_ctx->c2s_info.tuple4, sizeof(struct addr_tuple4)) == 0) + meta.is_e2i_dir = s_ctx->c2s_info.is_e2i_dir; + else + meta.is_e2i_dir = s_ctx->s2c_info.is_e2i_dir; + + if (meta.is_e2i_dir) + { + route_ctx_copy(&meta.route_ctx, &s_ctx->raw_meta_e2i->route_ctx); + } + else + { + route_ctx_copy(&meta.route_ctx, &s_ctx->raw_meta_i2e->route_ctx); + } + packet_io_set_metadata(tx_buffs[0], &meta); + marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread->thread_index, tx_buffs, 1); +} + +void handle_raw_packet_from_tap(const char *data, int len, void *args) +{ + char *src_mac = NULL; + char *dst_mac = NULL; + struct acceptor_thread_ctx *thread = (struct acceptor_thread_ctx *)args; + struct acceptor_ctx *acceptor_ctx = thread->ref_acceptor_ctx; + struct packet_io *packet_io = thread->ref_io; + + struct addr_tuple4 inner_addr; + struct raw_pkt_parser raw_parser; + memset(&inner_addr, 0, sizeof(struct addr_tuple4)); + raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); + raw_packet_parser_parse(&raw_parser, (const void *)data, len); + raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); + + struct session_node *node = session_table_search_by_addr(thread->session_table, &inner_addr); + if (node == NULL) + { + char *addr_string = addr_tuple4_to_str(&inner_addr); + TFE_LOG_ERROR(g_default_logger, "%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_string); + free(addr_string); + return; + } + struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; + + marsio_buff_t *tx_buffs[1]; + int alloc_ret = marsio_buff_malloc_device(packet_io->dev_nf_interface.mr_dev, tx_buffs, 1, 0, thread->thread_index); + if (alloc_ret < 0){ + TFE_LOG_ERROR(g_default_logger, "Failed at alloc marsio buffer, ret = %d, thread_seq = %d", + alloc_ret, thread->thread_index); + return; + } + + char *dst = marsio_buff_append(tx_buffs[0], len); + memcpy(dst, data, len); + + struct metadata meta = {0}; + meta.session_id = s_ctx->session_id; + meta.raw_data = dst; + meta.raw_len = len; + meta.is_decrypted = 0; + meta.is_ctrl_pkt = 0; + meta.l7offset = 0; + + if (memcmp(&inner_addr, &s_ctx->c2s_info.tuple4, sizeof(struct addr_tuple4)) == 0) + { + meta.is_e2i_dir = s_ctx->c2s_info.is_e2i_dir; + src_mac = s_ctx->client_mac; + dst_mac = s_ctx->server_mac; + } + else + { + meta.is_e2i_dir = s_ctx->s2c_info.is_e2i_dir; + src_mac = s_ctx->server_mac; + dst_mac = s_ctx->client_mac; + } + + if (meta.is_e2i_dir) + { + sids_copy(&meta.sids, &s_ctx->raw_meta_e2i->sids); + route_ctx_copy(&meta.route_ctx, &s_ctx->raw_meta_e2i->route_ctx); + } + else + { + // raw_meta_i2e->raw_data maybe is null + sids_copy(&meta.sids, &s_ctx->raw_meta_i2e->sids); + route_ctx_copy(&meta.route_ctx, &s_ctx->raw_meta_i2e->route_ctx); + } + + + packet_io_set_metadata(tx_buffs[0], &meta); + add_ether_header(dst, src_mac, dst_mac); + marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread->thread_index, tx_buffs, 1); +} diff --git a/common/src/tfe_utils.cpp b/common/src/tfe_utils.cpp index 4e8ef84..0ae3492 100644 --- a/common/src/tfe_utils.cpp +++ b/common/src/tfe_utils.cpp @@ -376,7 +376,7 @@ int get_mac_by_device_name(const char *dev_name, char *mac_buff) } unsigned char *mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; - sprintf(mac_buff, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + memcpy(mac_buff, mac, 6); close(fd); return 0; diff --git a/common/test/test_mpack.cpp b/common/test/test_mpack.cpp new file mode 100644 index 0000000..65fdc93 --- /dev/null +++ b/common/test/test_mpack.cpp @@ -0,0 +1,16 @@ +#include +#include + +#include "tfe_ctrl_packet.h" + +// TEST(MPACK, PARSE) +// { +// struct ctrl_pkt_parser handler; +// parse_messagepack(); +// } + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/common/test/test_session_table.cpp b/common/test/test_session_table.cpp new file mode 100644 index 0000000..a804dc0 --- /dev/null +++ b/common/test/test_session_table.cpp @@ -0,0 +1,274 @@ +#include +#include + +#include "tfe_session_table.h" + +TEST(STREAM_TABLE, INSERT) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == -1); + EXPECT_TRUE(session_table_count(table) == 1); + + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == -1); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, SEARCH_BY_ID) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + INIT_ADDR_V4(addr3, "1.1.1.1", 1111, "2.2.2.2", 2222); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Search By Session ID + struct session_node *node = NULL; + node = session_table_search_by_id(table, 1); + EXPECT_TRUE(node != nullptr); + EXPECT_STREQ((const char *)node->value, "HELLO"); + node = session_table_search_by_id(table, 2); + EXPECT_TRUE(node != nullptr); + EXPECT_STREQ((const char *)node->value, "WORLD"); + node = session_table_search_by_id(table, 3); + EXPECT_TRUE(node == nullptr); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, SEARCH_BY_ADDR) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + INIT_ADDR_V4(addr3, "1.1.1.1", 1111, "2.2.2.2", 2222); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Search By Session Addr + struct session_node *node = NULL; + node = session_table_search_by_addr(table, &addr1); + EXPECT_TRUE(node != nullptr); + EXPECT_STREQ((const char *)node->value, "HELLO"); + node = session_table_search_by_addr(table, &addr2); + EXPECT_TRUE(node != nullptr); + EXPECT_STREQ((const char *)node->value, "WORLD"); + node = session_table_search_by_addr(table, &addr3); + EXPECT_TRUE(node == nullptr); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, SEARCH_BY_REVERSE_ADDR) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + struct addr_tuple4 addr1_reverse; + struct addr_tuple4 addr2_reverse; + addr_tuple4_reverse(&addr1, &addr1_reverse); + addr_tuple4_reverse(&addr2, &addr2_reverse); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Search By Session Reverse Addr + struct session_node *node = NULL; + node = session_table_search_by_addr(table, &addr1_reverse); + EXPECT_TRUE(node != nullptr); + EXPECT_STREQ((const char *)node->value, "HELLO"); + node = session_table_search_by_addr(table, &addr2_reverse); + EXPECT_TRUE(node != nullptr); + EXPECT_STREQ((const char *)node->value, "WORLD"); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, DELETE_BY_ID) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + struct addr_tuple4 addr1_reverse; + struct addr_tuple4 addr2_reverse; + addr_tuple4_reverse(&addr1, &addr1_reverse); + addr_tuple4_reverse(&addr2, &addr2_reverse); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Delete By Session ID + EXPECT_TRUE(session_table_delete_by_id(table, 1) == 0); + EXPECT_TRUE(session_table_search_by_id(table, 1) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1_reverse) == NULL); + EXPECT_TRUE(session_table_count(table) == 1); + + EXPECT_TRUE(session_table_delete_by_id(table, 2) == 0); + EXPECT_TRUE(session_table_search_by_id(table, 2) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2_reverse) == NULL); + EXPECT_TRUE(session_table_count(table) == 0); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, DELETE_BY_ADDR) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + struct addr_tuple4 addr1_reverse; + struct addr_tuple4 addr2_reverse; + addr_tuple4_reverse(&addr1, &addr1_reverse); + addr_tuple4_reverse(&addr2, &addr2_reverse); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Delete By Session Addr + EXPECT_TRUE(session_table_delete_by_addr(table, &addr1) == 0); + EXPECT_TRUE(session_table_search_by_id(table, 1) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1_reverse) == NULL); + EXPECT_TRUE(session_table_count(table) == 1); + + EXPECT_TRUE(session_table_delete_by_addr(table, &addr2) == 0); + EXPECT_TRUE(session_table_search_by_id(table, 2) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2_reverse) == NULL); + EXPECT_TRUE(session_table_count(table) == 0); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, DELETE_BY_REVERSE_ADDR) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + struct addr_tuple4 addr1_reverse; + struct addr_tuple4 addr2_reverse; + addr_tuple4_reverse(&addr1, &addr1_reverse); + addr_tuple4_reverse(&addr2, &addr2_reverse); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_count(table) == 2); + + // TEST Delete By Session Reverse Addr + EXPECT_TRUE(session_table_delete_by_addr(table, &addr1_reverse) == 0); + EXPECT_TRUE(session_table_search_by_id(table, 1) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1_reverse) == NULL); + EXPECT_TRUE(session_table_count(table) == 1); + + EXPECT_TRUE(session_table_delete_by_addr(table, &addr2_reverse) == 0); + EXPECT_TRUE(session_table_search_by_id(table, 2) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2) == NULL); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2_reverse) == NULL); + EXPECT_TRUE(session_table_count(table) == 0); + + // TEST Destory + session_table_destory(table); +} + +TEST(STREAM_TABLE, RESET) +{ + // TEST Create + struct session_table *table = session_table_create(); + EXPECT_TRUE(table != nullptr); + + char *val_hello = strdup("HELLO"); + char *val_world = strdup("WORLD"); + INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321); + INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342); + + // TEST Insert + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0); + EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == -1); + EXPECT_TRUE(session_table_count(table) == 1); + + // TEST Reset + session_table_reset(table); + EXPECT_TRUE(session_table_search_by_id(table, 1) == nullptr); + EXPECT_TRUE(session_table_search_by_addr(table, &addr1) == nullptr); + EXPECT_TRUE(session_table_count(table) == 0); + + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == 0); + EXPECT_TRUE(session_table_insert(table, 2, &addr2, val_world, free) == -1); + EXPECT_TRUE(session_table_search_by_id(table, 2) != nullptr); + EXPECT_TRUE(session_table_search_by_addr(table, &addr2) != nullptr); + EXPECT_TRUE(session_table_count(table) == 1); + + // TEST Destory + session_table_destory(table); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/platform/src/acceptor_kni_v4.cpp b/platform/src/acceptor_kni_v4.cpp index 329d8bc..68a6613 100644 --- a/platform/src/acceptor_kni_v4.cpp +++ b/platform/src/acceptor_kni_v4.cpp @@ -63,22 +63,22 @@ static void *worker_thread_cycle(void *arg) handle_raw_packet_from_tap(thread_ctx->tap_ctx->buff, pkg_len, thread_ctx); } - if ((pkg_len = tfe_tap_read_per_thread(thread_ctx->tap_ctx->tap_c, thread_ctx->tap_ctx->buff, thread_ctx->tap_ctx->buff_size, g_default_logger)) > 0) - { - handle_decryption_packet_from_tap(thread_ctx->tap_ctx->buff, pkg_len, thread_ctx); - } + // if ((pkg_len = tfe_tap_read_per_thread(thread_ctx->tap_ctx->tap_c, thread_ctx->tap_ctx->buff, thread_ctx->tap_ctx->buff_size, g_default_logger)) > 0) + // { + // handle_decryption_packet_from_tap(thread_ctx->tap_ctx->buff, pkg_len, thread_ctx); + // } - if ((pkg_len = tfe_tap_read_per_thread(thread_ctx->tap_ctx->tap_s, thread_ctx->tap_ctx->buff, thread_ctx->tap_ctx->buff_size, g_default_logger)) > 0) - { - handle_decryption_packet_from_tap(thread_ctx->tap_ctx->buff, pkg_len, thread_ctx); - } + // if ((pkg_len = tfe_tap_read_per_thread(thread_ctx->tap_ctx->tap_s, thread_ctx->tap_ctx->buff, thread_ctx->tap_ctx->buff_size, g_default_logger)) > 0) + // { + // handle_decryption_packet_from_tap(thread_ctx->tap_ctx->buff, pkg_len, thread_ctx); + // } } - global_metrics_dump(acceptor_ctx->metrics); + - if (n_pkt_recv_from_nf == 0) - { - packet_io_thread_wait(handle, thread_ctx, 0); - } + // if (n_pkt_recv_from_nf == 0) + // { + // packet_io_thread_wait(handle, thread_ctx, 0); + // } if (__atomic_fetch_add(&thread_ctx->session_table_need_reset, 0, __ATOMIC_RELAXED) > 0) { diff --git a/platform/src/proxy.cpp b/platform/src/proxy.cpp index df4285a..e09d3e0 100644 --- a/platform/src/proxy.cpp +++ b/platform/src/proxy.cpp @@ -60,6 +60,7 @@ /* Systemd */ #include +#include "tfe_acceptor_kni.h" extern struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger); extern struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger); @@ -292,6 +293,8 @@ static void __gc_handler_cb(evutil_socket_t fd, short what, void * arg) FS_operate(ctx->fs_handle, ctx->fs_id[i], 0, FS_OP_SET, ATOMIC_READ(&(ctx->stat_val[i]))); } + // global_metrics_dump(ctx->kni_v4_acceptor->acceptor->metrics); + FS_passive_output(ctx->fs_handle); return; } diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index c750568..ea7d58d 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -379,7 +379,7 @@ set_property(TARGET libnetfilter_queue-static PROPERTY INTERFACE_INCLUDE_DIRECTO ### msgpack-c 6.0.0 ExternalProject_Add(msgpack-c PREFIX msgpack-c URL ${CMAKE_CURRENT_SOURCE_DIR}/msgpack-c-6.0.0.tar.gz - URL_MD5 f930a80b118a20de2be3211b0706f562 + URL_MD5 adc08f48550ce772fe24c0b41166b0de CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DMSGPACK_BUILD_TESTS=OFF) diff --git a/vendor/msgpack-c-6.0.0.tar.gz b/vendor/msgpack-c-6.0.0.tar.gz index 4a4a47a..185e89c 100644 Binary files a/vendor/msgpack-c-6.0.0.tar.gz and b/vendor/msgpack-c-6.0.0.tar.gz differ