diff --git a/bin/tsg_static_tableinfo.conf b/bin/tsg_static_tableinfo.conf index 6a40ae0..0cdf375 100644 --- a/bin/tsg_static_tableinfo.conf +++ b/bin/tsg_static_tableinfo.conf @@ -10,8 +10,10 @@ #id name type src_charset dst_charset do_merge cross_cache quickswitch 0 TSG_SECURITY_COMPILE compile escape -- 0 TRAFFIC_SHAPING_COMPILE compile escape -- +0 SERVICE_CHAINING_COMPILE compile escape -- 1 GROUP_COMPILE_RELATION group2compile -- 1 GROUP_SHAPING_COMPILE_RELATION group2compile -- +1 GROUP_SERVICE_CHAINING_COMPILE_RELATION group2compile -- 2 GROUP_GROUP_RELATION group2group -- 3 TSG_OBJ_IP_ADDR ip_plus UTF8 UTF8 no 0 3 TSG_OBJ_IP_LEARNING_ADDR ip_plus UTF8 UTF8 no 0 diff --git a/ctest/CMakeLists.txt b/ctest/CMakeLists.txt index cf8a9d9..cc7d15b 100644 --- a/ctest/CMakeLists.txt +++ b/ctest/CMakeLists.txt @@ -12,8 +12,10 @@ add_test(NAME COPY_GTEST_MAAT_RULE COMMAND sh -c "cp -r ${CMAKE_SOURCE_DIR}/test #add_test(NAME COPY_GTEST_RULE_BIN COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_rule ${CMAKE_BINARY_DIR}/testing/") add_test(NAME COPY_GTEST_MASTER_BIN COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_master ${CMAKE_BINARY_DIR}/testing/") +add_test(NAME COPY_GTEST_SYNC_SESSION_STATE_BIN COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_sync_session_state ${CMAKE_BINARY_DIR}/testing/") set(GTEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing) #add_test(NAME GTEST_RULE COMMAND gtest_rule WORKING_DIRECTORY ${GTEST_RUN_DIR}) add_test(NAME GTEST_MASTER COMMAND gtest_master WORKING_DIRECTORY ${GTEST_RUN_DIR}) +add_test(NAME GTEST_SYNC_SESSION_STATE COMMAND gtest_sync_session_state WORKING_DIRECTORY ${GTEST_RUN_DIR}) diff --git a/inc/tsg_rule.h b/inc/tsg_rule.h index 6e5853c..44ae652 100644 --- a/inc/tsg_rule.h +++ b/inc/tsg_rule.h @@ -18,6 +18,7 @@ #define TSG_ACTION_DENY 0x10 #define TSG_ACTION_SHAPING 0x20 #define TSG_ACTION_MANIPULATE 0x30 +#define TSG_ACTION_S_CHAINING 0x40 #define TSG_ACTION_BYPASS 0x80 #define TSG_ACTION_MAX 0x80 @@ -95,5 +96,6 @@ int tsg_scan_fqdn_category_id(Maat_feather_t maat_feather, const struct streamin int tsg_notify_hited_monitor_result(const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, int thread_seq); int tsg_notify_hited_shaping_result(const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, int thread_seq); int tsg_notify_hited_security_result(const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, int thread_seq); +int tsg_notify_hited_s_chaining_result(const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, int thread_seq); #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2efdb3b..8860ac1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,8 @@ cmake_minimum_required(VERSION 2.8) add_definitions(-fPIC) -set(SRC tsg_entry.cpp tsg_rule.cpp tsg_ssl_utils.cpp tsg_send_log.cpp tsg_statistic.cpp tsg_ssh_utils.cpp tsg_gtp_signaling.cpp tsg_action.cpp tsg_leaky_bucket.cpp tsg_dns.cpp tsg_icmp.cpp tsg_tamper.cpp tsg_bridge.cpp) +set(SRC tsg_entry.cpp tsg_rule.cpp tsg_ssl_utils.cpp tsg_send_log.cpp tsg_statistic.cpp tsg_ssh_utils.cpp tsg_gtp_signaling.cpp tsg_action.cpp tsg_leaky_bucket.cpp tsg_dns.cpp tsg_icmp.cpp tsg_tamper.cpp tsg_bridge.cpp +tsg_sync_state.cpp) include_directories(${CMAKE_SOURCE_DIR}/inc) include_directories(/opt/MESA/include/MESA/) diff --git a/src/tsg_bridge.cpp b/src/tsg_bridge.cpp index 2368acc..e294321 100644 --- a/src/tsg_bridge.cpp +++ b/src/tsg_bridge.cpp @@ -82,6 +82,15 @@ void free_shaping_result(const struct streaminfo *stream, int bridge_id, void *d } } +void free_s_chaining_result(const struct streaminfo *stream, int bridge_id, void *data) +{ + if(data!=NULL) + { + dictator_free(stream->threadnum, data); + data=NULL; + } +} + void free_policy_label(const struct streaminfo *a_stream, int bridge_id, void *data) { if(data!=NULL) @@ -159,6 +168,9 @@ int tsg_init_bridge(const char *conffile) MESA_load_profile_string_def(conffile, "SYSTEM", "POLICY_PRIORITY_BRIDGE_NAME", g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].name, MAX_BRIDGE_NAME_LEN, "TSG_POLICY_PRIORITY"); g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].free_cb=free_policy_label; + MESA_load_profile_string_def(conffile, "SYSTEM", "S_CHAINING_RESULT_BRIDGE_NAME", g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].name, MAX_BRIDGE_NAME_LEN, "SERVICE_CHAINING_RESULT"); + g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].free_cb=free_s_chaining_result; + for(int i=0; iresult[hited_s_chaining->result_num]); + int num=MIN(MAX_RESULT_NUM-hited_s_chaining->result_num, p_result_num); + for(int i=0; iresult_num+inc_result_num; j++) + { + if(p_result[i].config_id==hited_s_chaining->result[j].config_id) + { + repeat_result=1; + break; + } + } + + if(repeat_result==0) + { + memcpy(&(inc_result[inc_result_num++]), &(p_result[i]), sizeof(struct Maat_rule_t)); + } + } + + if(inc_result_num==0) + { + return ; + } + + if(hited_s_chaining->sid!=g_tsg_para.service_chaining_sid) + { + struct segment_id_list sid_list={0}; + sid_list.sid_list[0]=(unsigned short)g_tsg_para.service_chaining_sid; + sid_list.sz_sidlist=1; + MESA_set_stream_opt(a_stream, MSO_STREAM_PREPLEND_SEGMENT_ID_LIST, (void *)&sid_list, sizeof(struct segment_id_list)); + hited_s_chaining->sid=g_tsg_para.service_chaining_sid; + } + + struct update_policy policy_array; + policy_array.id_num=inc_result_num; + policy_array.type=POLICY_UPDATE_SERVICE_CHAINING; + + for(int i=0; iresult_num+=inc_result_num; + int ret=tsg_set_xxx_to_bridge((struct streaminfo *)a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, (void *)hited_s_chaining); + if(ret<0) + { + free_shaping_result(a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, (void *)hited_s_chaining); + return ; + } + + FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_S_CHAINING], 0, FS_OP_ADD, inc_result_num); + set_method_to_tcpall(a_stream, TSG_METHOD_TYPE_UNKNOWN, thread_seq); +} + +int tsg_notify_hited_s_chaining_result(const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, int thread_seq) +{ + set_s_chaining_result_to_bridge(a_stream, result, result_num, thread_seq); + return 0; +} + +static void set_shaping_result_to_bridge(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, int p_result_num, int thread_seq) { if(p_result==NULL || p_result_num==0) { @@ -1199,11 +1330,14 @@ static void set_shaping_result_to_project(const struct streaminfo *a_stream, str free_shaping_result(a_stream, g_tsg_para.bridge[BRIDGE_TYPE_NOTIFY_SHAPING_RESULT].id, (void *)shaping_label); return ; } + + FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SHAPING], 0, FS_OP_ADD, inc_result_num); + set_method_to_tcpall(a_stream, TSG_METHOD_TYPE_UNKNOWN, thread_seq); } int tsg_notify_hited_shaping_result(const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, int thread_seq) { - set_shaping_result_to_project(a_stream, result, result_num, thread_seq); + set_shaping_result_to_bridge(a_stream, result, result_num, thread_seq); return 0; } @@ -1240,7 +1374,7 @@ int set_log_field_to_project(const struct streaminfo * a_stream, char *domain, v return 0; } -void set_security_result_to_project(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, int p_result_num, PULL_RESULT_TYPE result_type, int thread_seq) +static void set_security_result_to_bridge(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, int p_result_num, PULL_RESULT_TYPE result_type, int thread_seq) { if(p_result==NULL || p_result_num==0) { @@ -1300,7 +1434,7 @@ void set_security_result_to_project(const struct streaminfo *a_stream, struct Ma int tsg_notify_hited_security_result(const struct streaminfo * a_stream, struct Maat_rule_t * p_result, int p_result_num, int thread_seq) { - set_security_result_to_project(a_stream, p_result, p_result_num, PULL_FW_RESULT, thread_seq); + set_security_result_to_bridge(a_stream, p_result, p_result_num, PULL_FW_RESULT, thread_seq); return 0; } @@ -1817,12 +1951,15 @@ int scan_application_id_and_properties(const struct streaminfo *a_stream, struct static int master_deal_shaping_result(const struct streaminfo *a_stream, struct Maat_rule_t *shaping_result, int shaping_result_num) { - //get shaping rule - set_shaping_result_to_project(a_stream, shaping_result, shaping_result_num, a_stream->threadnum); + set_shaping_result_to_bridge(a_stream, shaping_result, shaping_result_num, a_stream->threadnum); - FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SHAPING], 0, FS_OP_ADD, 1); - set_method_to_tcpall(a_stream, TSG_METHOD_TYPE_UNKNOWN, a_stream->threadnum); + return 0; +} +static int master_deal_s_chaining_result(const struct streaminfo *a_stream, struct Maat_rule_t *s_chaining_result, int s_chaining_result_num) +{ + set_s_chaining_result_to_bridge(a_stream, s_chaining_result, s_chaining_result_num, a_stream->threadnum); + return 0; } @@ -1830,7 +1967,6 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, { struct Maat_rule_t *p_result=NULL; unsigned char state=APP_STATE_GIVEME; - struct Maat_rule_t shaping_result[MAX_RESULT_NUM]={0}; struct Maat_rule_t security_result[MAX_RESULT_NUM]={0}; int security_result_num=tsg_fetch_hited_security_result(result, hit_num, security_result, MAX_RESULT_NUM); @@ -1863,7 +1999,7 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, if(is_deny_after_N_packets(p_result)) { - set_security_result_to_project(a_stream, p_result, 1, PULL_FW_RESULT, a_stream->threadnum); + set_security_result_to_bridge(a_stream, p_result, 1, PULL_FW_RESULT, a_stream->threadnum); if(a_stream->type==STREAM_TYPE_TCP) { break; @@ -1882,7 +2018,7 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, break; } tsg_notify_hited_monitor_result(a_stream, result, hit_num, a_stream->threadnum); - set_security_result_to_project(a_stream, security_result, security_result_num, PULL_FW_RESULT, a_stream->threadnum); + set_security_result_to_bridge(a_stream, security_result, security_result_num, PULL_FW_RESULT, a_stream->threadnum); break; case TSG_ACTION_BYPASS: context->is_hited_allow=1; @@ -1900,7 +2036,7 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, break; } - set_security_result_to_project(a_stream, p_result, 1, PULL_KNI_RESULT, a_stream->threadnum); + set_security_result_to_bridge(a_stream, p_result, 1, PULL_KNI_RESULT, a_stream->threadnum); FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INTERCEPT], 0, FS_OP_ADD, 1); state=APP_STATE_DROPME|APP_STATE_KILL_OTHER; @@ -1913,12 +2049,20 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, set_log_field_to_project(a_stream, context->domain, context->para, context->proto, a_stream->threadnum); } + struct Maat_rule_t shaping_result[MAX_RESULT_NUM]={0}; int shaping_result_num=tsg_fetch_hited_shaping_result(result, hit_num, shaping_result, MAX_RESULT_NUM); if(state==APP_STATE_GIVEME && shaping_result_num>0) { master_deal_shaping_result(a_stream, shaping_result, shaping_result_num); } + struct Maat_rule_t s_chaining_result[MAX_RESULT_NUM]={0}; + int s_chaining_result_num=tsg_fetch_hited_s_chaining_result(result, hit_num, s_chaining_result, MAX_RESULT_NUM); + if(state==APP_STATE_GIVEME && s_chaining_result_num>0) + { + master_deal_s_chaining_result(a_stream, s_chaining_result, s_chaining_result_num); + } + return state; } @@ -2174,7 +2318,7 @@ static unsigned char tsg_master_data_entry(const struct streaminfo *a_stream, vo { continue; } - hit_num+=scan_application_id_and_properties(a_stream, hited_result+hit_num, MAX_RESULT_NUM-hit_num, context, &(gather_result[i]), thread_seq); + hit_num+=scan_application_id_and_properties(a_stream, hited_result+hit_num, MAX_TSG_ALL_RESULT_NUM-hit_num, context, &(gather_result[i]), thread_seq); } if(context->session_flag>0) @@ -2244,7 +2388,7 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns break; case TSG_ACTION_MONITOR: tsg_notify_hited_monitor_result(a_stream, security_result, hit_num, thread_seq); - set_security_result_to_project(a_stream, security_result, security_result_num, PULL_FW_RESULT,thread_seq); + set_security_result_to_bridge(a_stream, security_result, security_result_num, PULL_FW_RESULT,thread_seq); break; default: break; @@ -2256,6 +2400,13 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns { master_deal_shaping_result(a_stream, shaping_result, shaping_result_num); } + + struct Maat_rule_t s_chaining_result[MAX_RESULT_NUM]={0}; + int s_chaining_result_num=tsg_fetch_hited_s_chaining_result(hited_result, hit_num, s_chaining_result, MAX_RESULT_NUM); + if(state==APP_STATE_GIVEME && s_chaining_result_num>0) + { + master_deal_s_chaining_result(a_stream, s_chaining_result, s_chaining_result_num); + } } Maat_clean_status(&scan_mid); @@ -2348,6 +2499,8 @@ extern "C" unsigned char TSG_MASTER_UDP_ENTRY(const struct streaminfo *a_udp, vo { return APP_STATE_DROPME; } + + send_control_packet_in_pending(a_udp, a_udp->opstate); *pme=dictator_malloc(thread_seq, sizeof(struct udp_context)); memset(*pme, 0, sizeof(struct udp_context)); @@ -2380,6 +2533,8 @@ extern "C" unsigned char TSG_MASTER_UDP_ENTRY(const struct streaminfo *a_udp, vo { dictator_free(thread_seq, *pme); *pme=NULL; + + send_control_packet_in_closing(a_udp, a_udp->opstate); } return (state1|state2); @@ -2390,12 +2545,13 @@ extern "C" unsigned char TSG_MASTER_TCPALL_ENTRY(const struct streaminfo *a_tcp, struct tcpall_context *_context=(struct tcpall_context *)(*pme); if(*pme==NULL) - { + { + send_control_packet_in_pending(a_tcp, a_tcp->pktstate); *pme=(void *)tsg_get_xxx_from_bridge(a_tcp, g_tsg_para.bridge[BRIDGE_TYPE_ALL_CONTEXT].id); if(*pme==NULL) { *pme=(struct tcpall_context *)dictator_malloc(thread_seq, sizeof(struct tcpall_context)); - memset(*pme, 0, sizeof(struct tcpall_context)); + memset(*pme, 0, sizeof(struct tcpall_context)); tsg_set_xxx_to_bridge(a_tcp, g_tsg_para.bridge[BRIDGE_TYPE_ALL_CONTEXT].id, (void *)(*pme)); } @@ -2408,7 +2564,14 @@ extern "C" unsigned char TSG_MASTER_TCPALL_ENTRY(const struct streaminfo *a_tcp, _context->set_latency_flag=set_tcp_establish_latency_ms(a_tcp, thread_seq, a_packet); } - return tsg_master_all_entry(a_tcp, a_tcp->pktstate, pme, thread_seq, a_packet); + unsigned char state=tsg_master_all_entry(a_tcp, a_tcp->pktstate, pme, thread_seq, a_packet); + + if(state&APP_STATE_DROPME || a_tcp->pktstate==OP_STATE_CLOSE) + { + send_control_packet_in_closing(a_tcp, a_tcp->pktstate); + } + + return state; } extern "C" int TSG_MASTER_INIT() @@ -2456,6 +2619,8 @@ extern "C" int TSG_MASTER_INIT() MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "IENTIFY_APP_MAX_PKT_NUM", &g_tsg_para.identify_app_max_pkt_num, 20); MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "FEATURE_TAMPER", &g_tsg_para.feature_tamper, 0); + MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "SERVICE_CHAINING_SID", &g_tsg_para.service_chaining_sid, 1); + MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "SHAPING_SID", &g_tsg_para.shaping_sid, 2); ret=MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "DEVICE_SEQ_IN_DATA_CENTER", &g_tsg_para.device_seq_in_dc, 0); if(ret<0) @@ -2529,7 +2694,9 @@ extern "C" int TSG_MASTER_INIT() MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "INIT_GTP_HASH", "tsg_gtp_signaling_hash_init failed ..."); return -1; } - + + g_tsg_para.send_resetall=0; + return 0; } diff --git a/src/tsg_entry.h b/src/tsg_entry.h index 0418031..40bddef 100644 --- a/src/tsg_entry.h +++ b/src/tsg_entry.h @@ -34,6 +34,15 @@ typedef int atomic_t; #include #endif +#ifndef TM_FALSE +#define TM_FALSE 0 +#endif + +#ifndef TM_TRUE +#define TM_TRUE 1 +#endif + + #ifndef FLAG_FALSE #define FLAG_FALSE 0 #endif @@ -246,6 +255,6 @@ int tsg_scan_session_flags(Maat_feather_t maat_feather, const struct streaminfo int tsg_fetch_hited_security_result(struct Maat_rule_t *hited_result, int hited_result_num, struct Maat_rule_t *security_result, int security_result_num); int tsg_fetch_hited_shaping_result(struct Maat_rule_t *hited_result, int hited_result_num, struct Maat_rule_t *security_result, int security_result_num); - +int tsg_fetch_hited_s_chaining_result(struct Maat_rule_t *hited_result, int hited_result_num, struct Maat_rule_t *s_chaining_result, int s_chaining_result_num); #endif diff --git a/src/tsg_rule.cpp b/src/tsg_rule.cpp index 416082f..fe502d5 100644 --- a/src/tsg_rule.cpp +++ b/src/tsg_rule.cpp @@ -3464,7 +3464,7 @@ int tsg_fetch_hited_security_result(struct Maat_rule_t *hited_result, int hited_ int result_cnt=0; for(int i=0; i=s_chaining_result_num) + { + break; + } + + memcpy(&(s_chaining_result[result_cnt++]), &(hited_result[i]), sizeof(struct Maat_rule_t)); + } + + return result_cnt; +} + diff --git a/src/tsg_sync_state.cpp b/src/tsg_sync_state.cpp new file mode 100644 index 0000000..6149ad5 --- /dev/null +++ b/src/tsg_sync_state.cpp @@ -0,0 +1,180 @@ +#include +#include +#include +#include + +#include "tsg_sync_state.h" +#include "tsg_send_log.h" + +// i don't need this +int set_exec_profile_ids(const struct streaminfo *a_stream, struct parse_handle *p); + +const char *policy_key[ POLICY_UPDATE_MAX] = +{ + "service_chaining", + "shaping", +}; + +static int tsg_send_ctrl_pkt(const struct streaminfo *a_stream, cJSON *object) +{ + if (object == NULL) + { + return -1; + } + + char *payload = NULL; + uint64_t session_id = tsg_get_stream_id((struct streaminfo *)a_stream); + + // tsg_get_stream_id maybe return -1 + if (session_id && session_id != (uint64_t)-1) + { + char trace_id[128]={0}; + snprintf(trace_id, sizeof(trace_id), "%lu", session_id); + cJSON_AddStringToObject(object, "session_id", trace_id); + } + + cJSON_AddStringToObject(object, "tsync", "1.0"); + + payload = cJSON_PrintUnformatted(object); + if (payload == NULL) + { + cJSON_Delete(object); + return -1; + } + + // send// + sapp_inject_ctrl_pkt((struct streaminfo *)a_stream, SIO_DEFAULT, payload, strlen(payload)+1, a_stream->routedir); + + cJSON_free(payload); + cJSON_Delete(object); + + return 0; +} + +int tsg_send_session_state(const struct streaminfo *a_stream, unsigned char state) +{ + if (a_stream == NULL) + { + return -1; + } + + cJSON *object = cJSON_CreateObject(); + + if (state== OP_STATE_PENDING) + { + cJSON_AddStringToObject(object, "state", "opening"); + } + else if (state == OP_STATE_CLOSE) + { + cJSON_AddStringToObject(object, "state", "closing"); + } + else + { + cJSON_Delete(object); + return -1; + } + + return tsg_send_ctrl_pkt(a_stream, object); +} + +int tsg_sync_resetall_state(const struct streaminfo *a_stream) +{ + if (a_stream == NULL) + { + return -1; + } + + cJSON *object = cJSON_CreateObject(); + cJSON_AddStringToObject(object, "state", "resetall"); + + return tsg_send_ctrl_pkt(a_stream, object); +} + +int tsg_sync_policy_update(const struct streaminfo *a_stream, struct update_policy *policy_array, int policy_array_num) +{ + if (a_stream == NULL || policy_array == NULL || policy_array_num > (int) POLICY_UPDATE_MAX || policy_array_num <= 0) + { + return -1; + } + + cJSON *params_object = NULL; + cJSON *policy_arr = NULL; + cJSON *object = cJSON_CreateObject(); + + cJSON_AddStringToObject(object, "state", "active"); + cJSON_AddStringToObject(object, "method", "policy_update"); + params_object = cJSON_AddObjectToObject(object, "params"); + + for (int i = 0; i < policy_array_num; i ++) + { + policy_arr = cJSON_CreateIntArray(policy_array[i].ids, policy_array[i].id_num); + if (policy_arr == NULL || policy_array[i].type >= POLICY_UPDATE_MAX) + { + cJSON_Delete(object); + return -1; + } + + cJSON_AddItemToObject(params_object, policy_key[policy_array[i].type], policy_arr); + policy_arr = NULL; + } + + return tsg_send_ctrl_pkt(a_stream, object); +} + +int tsg_recv_control_pkt(const struct streaminfo *a_stream, const void *payload, int payload_len) +{ + if (a_stream == NULL || payload == NULL || payload_len == 0) + { + return -1; + } + + char *state = NULL; + char *method = NULL; + char *tsync = NULL; + cJSON *params_object = NULL; + cJSON *sf_ids_array = NULL; + struct parse_handle result = {0}; + + cJSON *object = cJSON_Parse((char *)payload); + if (object == NULL) + { + return -1; + } + + tsync = cJSON_GetObjectItem(object, "tsync")->valuestring; + memcpy(result.tsync, tsync, strlen(tsync)); + + //result.session_id = (uint64_t)atoll(cJSON_GetObjectItem(object, "session_id")->string); + + state = cJSON_GetObjectItem(object, "state")->valuestring; + memcpy(result.state, state, strlen(state)); + + method = cJSON_GetObjectItem(object, "method")->valuestring; + memcpy(result.method, method, strlen(method)); + + params_object = cJSON_GetObjectItem(object, "params"); + sf_ids_array = cJSON_GetObjectItem(params_object, "sf_profile_ids"); + result.sf_ids.id_num = cJSON_GetArraySize(sf_ids_array); + for (int i = 0; i < result.sf_ids.id_num; i ++) + { + result.sf_ids.ids[i] = cJSON_GetArrayItem(sf_ids_array, i)->valueint; + } + + //set_exec_profile_ids(a_stream, &result); + + cJSON_Delete(object); + return 0; +} + +int tsg_sync_closing_state(const struct streaminfo *a_stream, unsigned char state) +{ + return tsg_send_session_state(a_stream, state); +} + +int tsg_sync_opening_state(const struct streaminfo *a_stream, unsigned char state) +{ + tsg_send_session_state(a_stream, state); + + return 0; +} + diff --git a/src/tsg_sync_state.h b/src/tsg_sync_state.h new file mode 100644 index 0000000..2a900fa --- /dev/null +++ b/src/tsg_sync_state.h @@ -0,0 +1,40 @@ +#ifndef TSG_SESSION_STATE_H +#define TSG_SESSION_STATE_H + +#include +#include + +enum policy_type +{ + POLICY_UPDATE_SERVICE_CHAINING = 0, + POLICY_UPDATE_SHAPING, + POLICY_UPDATE_MAX +}; + +struct update_policy +{ + enum policy_type type; + int id_num; + int ids[8]; +}; + +// i don't need this +struct parse_handle +{ + char tsync[8]; + uint64_t session_id; + char state[8]; + char method[16]; + struct update_policy sf_ids; +}; + +int tsg_sync_resetall_state(const struct streaminfo *a_stream); +int tsg_send_session_state(const struct streaminfo *a_stream, unsigned char state); +int tsg_sync_opening_state(const struct streaminfo *a_stream, unsigned char state); +int tsg_sync_closing_state(const struct streaminfo *a_stream, unsigned char state); +int tsg_sync_policy_update(const struct streaminfo *a_stream, struct update_policy *policy_array, int policy_array_num); + +int tsg_recv_control_pkt(const struct streaminfo *a_stream, const void *payload, int payload_len); + + +#endif //TSG_SESSION_STATE_H diff --git a/src/tsg_variable.h b/src/tsg_variable.h index f3d1546..5969a18 100644 --- a/src/tsg_variable.h +++ b/src/tsg_variable.h @@ -13,6 +13,11 @@ enum TSG_FS2_TYPE TSG_FS2_HIT_SHARE, TSG_FS2_INTERCEPT, TSG_FS2_SHAPING, + TSG_FS2_S_CHAINING, + TSG_FS2_CTRL_OPENING, + TSG_FS2_CTRL_CLOSING, + TSG_FS2_CTRL_ACTIVE, + TSG_FS2_CTRL_RESETALL, TSG_FS2_EXCLUSION, TSG_FS2_APP_DPKT_RESULT, TSG_FS2_APP_Q_RESULT, @@ -124,7 +129,7 @@ enum MASTER_DYNAMIC_TABLE #endif #ifndef MAX_TSG_ALL_RESULT_NUM -#define MAX_TSG_ALL_RESULT_NUM MAX_RESULT_NUM*2 +#define MAX_TSG_ALL_RESULT_NUM MAX_RESULT_NUM*3 #endif #ifndef MAX_STRING_LEN32 @@ -171,6 +176,8 @@ typedef struct tsg_para int hash_slot_size; int hash_thread_safe; int feature_tamper; + int service_chaining_sid; + int shaping_sid; enum DEPLOY_MODE deploy_mode; int scan_time_interval; int identify_app_max_pkt_num; @@ -191,6 +198,7 @@ typedef struct tsg_para char table_name[TABLE_MAX][MAX_TABLE_NAME_LEN]; char dyn_table_name[DYN_TABLE_MAX][MAX_TABLE_NAME_LEN]; struct bridge_info bridge[BRIDGE_TYPE_MAX]; + int send_resetall; void *logger; void *maat_logger; struct reset_argv reset; diff --git a/test/bin/gtest_maat.json b/test/bin/gtest_maat.json index b72d3a9..feaab2f 100644 --- a/test/bin/gtest_maat.json +++ b/test/bin/gtest_maat.json @@ -4,7 +4,7 @@ "group2group_table": "GROUP_GROUP_RELATION", "rules": [ { - "compile_id": 2, + "compile_id": 1, "service": 0, "action": 1, "do_blacklist": 0, @@ -36,6 +36,40 @@ ] } ] + }, + { + "compile_id": 2, + "service": 0, + "action": 16, + "do_blacklist": 0, + "do_log": 1, + "effective_rage": 0, + "user_region": "{\"method\":\"rate_limit\",\"bps\":1024,\"packet_capture\":{\"enable\":1,\"capture_depth\":2000}}", + "is_valid": "yes", + "groups": [ + { + "group_name": "OBJ_DST_IP_ADDR", + "virtual_table": "TSG_SECURITY_SOURCE_ADDR", + "not_flag": 0, + "regions": [ + { + "table_type": "ip_plus", + "table_name": "TSG_OBJ_IP_ADDR", + "table_content": { + "addr_type": "ipv4", + "saddr_format": "range", + "src_ip1": "0.0.0.0", + "src_ip2": "255.255.255.255", + "sport_format": "range", + "src_port1": "0", + "src_port2": "0", + "protocol": 0, + "direction": "double" + } + } + ] + } + ] } ], "plugin_table": [ diff --git a/test/src/CMakeLists.txt b/test/src/CMakeLists.txt index 3f3a01b..0db2be3 100644 --- a/test/src/CMakeLists.txt +++ b/test/src/CMakeLists.txt @@ -25,7 +25,11 @@ set(TSG_MASTER_SRC ${PROJECT_SOURCE_DIR}/src/tsg_entry.cpp ${PROJECT_SOURCE_DIR}/src/tsg_icmp.cpp ${PROJECT_SOURCE_DIR}/src/tsg_tamper.cpp ${PROJECT_SOURCE_DIR}/src/tsg_bridge.cpp + ${PROJECT_SOURCE_DIR}/src/tsg_sync_state.cpp ) add_executable(gtest_master ${TSG_MASTER_SRC} gtest_kafka.cpp gtest_common.cpp gtest_master.cpp) target_link_libraries(gtest_master gtest-static ctemplate-static cjson MESA_prof_load MESA_handle_logger MESA_jump_layer MESA_field_stat2 maatframe MESA_htable) + +add_executable(gtest_sync_session_state ${PROJECT_SOURCE_DIR}/src/tsg_sync_state.cpp gtest_common.cpp gtest_session_state.cpp) +target_link_libraries(gtest_sync_session_state gtest-static cjson ctemplate-static) diff --git a/test/src/gtest_common.cpp b/test/src/gtest_common.cpp index 18e138b..e7dd59b 100644 --- a/test/src/gtest_common.cpp +++ b/test/src/gtest_common.cpp @@ -3,6 +3,12 @@ const char *gtest_addrlist="127.0.0.1.37690>127.0.0.1.443"; +struct gtest_ctrl_pkt +{ + char buf[1024]; + int len; +}ctrl_pkt; + void dictator_free(int thread_seq, void * pbuf) { free(pbuf); @@ -34,6 +40,20 @@ int sapp_inject_pkt(struct streaminfo * stream, enum sapp_inject_opt sio, const return 0; } +int sapp_inject_ctrl_pkt(struct streaminfo * stream, enum sapp_inject_opt sio, const void * payload, int payload_len, unsigned char snd_routedir) +{ + memset(&ctrl_pkt, 0, 1024); + memcpy(ctrl_pkt.buf, payload, payload_len); + ctrl_pkt.len = payload_len; + + return 0; +} + +int get_ctrl_pkt(char *buf, int len) +{ + memcpy(buf, ctrl_pkt.buf, MIN(len, ctrl_pkt.len)); + return MIN(len, ctrl_pkt.len); +} unsigned char MESA_dir_reverse(unsigned char raw_route_dir) { diff --git a/test/src/gtest_master.cpp b/test/src/gtest_master.cpp index 98b6074..e5b5289 100644 --- a/test/src/gtest_master.cpp +++ b/test/src/gtest_master.cpp @@ -344,98 +344,125 @@ TEST(TSGMaster, SecurityDuplicatePolicyMultipleNotify) EXPECT_EQ(nullptr, stream_bridge_async_data_get(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id)); } -extern void set_security_result_to_project(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, int p_result_num, PULL_RESULT_TYPE result_type, int thread_seq); +extern void set_s_chaining_result_to_bridge(const struct streaminfo * a_stream, struct Maat_rule_t * p_result, int p_result_num, int thread_seq); -TEST(TSGMaster, SecurityPolicyIntercept) +TEST(TSGMaster, ServiceChainingPolicyNotify) { const struct streaminfo a_stream={0}; - struct Maat_rule_t security_result[MAX_RESULT_NUM]={0}; - struct identify_info identify_info; - - security_result[1].action=TSG_ACTION_INTERCEPT; - security_result[1].config_id=TSG_ACTION_INTERCEPT; - - // Set Intercept - set_security_result_to_project((struct streaminfo *)&a_stream, &security_result[1], 1, PULL_KNI_RESULT, 0); - - int ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_FW_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(0, ret); - - ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_KNI_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(1, ret); - EXPECT_EQ(TSG_ACTION_INTERCEPT, security_result[2].action); - EXPECT_EQ(TSG_ACTION_INTERCEPT, security_result[2].config_id); + struct Maat_rule_t s_chaining_result[MAX_RESULT_NUM]={0}; - ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_ALL_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(1, ret); - EXPECT_EQ(TSG_ACTION_INTERCEPT, security_result[2].action); - EXPECT_EQ(TSG_ACTION_INTERCEPT, security_result[2].config_id); + for(int i=0; isid); + EXPECT_EQ(MAX_RESULT_NUM/2, hited_s_chaining->result_num); + for(int i=0; iresult_num; i++) + { + EXPECT_EQ(TSG_ACTION_S_CHAINING, hited_s_chaining->result[i].action); + EXPECT_EQ(TSG_ACTION_S_CHAINING+i, hited_s_chaining->result[i].config_id); + } - struct policy_priority_label *priority_label=(struct policy_priority_label *)tsg_get_xxx_from_bridge(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id); - EXPECT_NE(nullptr, priority_label); - EXPECT_EQ(1, priority_label->security_result_num); - EXPECT_EQ(TSG_ACTION_INTERCEPT, priority_label->security_result[0].action); - EXPECT_EQ(TSG_ACTION_INTERCEPT, priority_label->security_result[0].config_id); - - free_policy_label(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id, (void *)priority_label); - stream_bridge_async_data_put(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id, NULL); - EXPECT_EQ(nullptr, stream_bridge_async_data_get(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id)); + free_shaping_result(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, (void *)hited_s_chaining); + stream_bridge_async_data_put(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, NULL); + EXPECT_EQ(nullptr, stream_bridge_async_data_get(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id)); } - -TEST(TSGMaster, SecurityMultiplePolicyMonitorToIntercept) +TEST(TSGMaster, ServiceChainingDuplicatePolicyMultipleNotify) { const struct streaminfo a_stream={0}; - struct Maat_rule_t security_result[MAX_RESULT_NUM]={0}; - struct identify_info identify_info; + struct Maat_rule_t s_chaining_result[MAX_RESULT_NUM]={0}; - security_result[0].action=TSG_ACTION_MONITOR; - security_result[0].config_id=TSG_ACTION_MONITOR; - - security_result[1].action=TSG_ACTION_INTERCEPT; - security_result[1].config_id=TSG_ACTION_INTERCEPT; - - // First Monitor, second Intercpt - tsg_notify_hited_security_result(&a_stream, &security_result[0], 1, 0); - - int ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_KNI_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(0, ret); + // first + for(int i=0; isid); + EXPECT_EQ(MAX_RESULT_NUM/2, hited_s_chaining->result_num); + for(int i=0; iresult_num; i++) + { + EXPECT_EQ(TSG_ACTION_S_CHAINING, hited_s_chaining->result[i].action); + EXPECT_EQ(TSG_ACTION_S_CHAINING+i, hited_s_chaining->result[i].config_id); + } - ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_ALL_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(1, ret); - EXPECT_EQ(TSG_ACTION_MONITOR, security_result[2].action); - EXPECT_EQ(TSG_ACTION_MONITOR, security_result[2].config_id); - - // Set Intercept - set_security_result_to_project((struct streaminfo *)&a_stream, &security_result[1], 1, PULL_KNI_RESULT, 0); - - ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_FW_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(0, ret); - - ret=tsg_pull_policy_result((struct streaminfo *)&a_stream, PULL_KNI_RESULT, &(security_result[2]), 1, &identify_info); - EXPECT_EQ(1, ret); - EXPECT_EQ(TSG_ACTION_INTERCEPT, security_result[2].action); - EXPECT_EQ(TSG_ACTION_INTERCEPT, security_result[2].config_id); + // second + for(int i=0; isid); + EXPECT_EQ(MAX_RESULT_NUM/2, hited_s_chaining->result_num); + for(int i=0; iresult_num; i++) + { + EXPECT_EQ(TSG_ACTION_S_CHAINING, hited_s_chaining->result[i].action); + EXPECT_EQ(TSG_ACTION_S_CHAINING+i, hited_s_chaining->result[i].config_id); + } - struct policy_priority_label *priority_label=(struct policy_priority_label *)tsg_get_xxx_from_bridge(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id); - EXPECT_NE(nullptr, priority_label); - EXPECT_EQ(1, priority_label->security_result_num); - EXPECT_EQ(TSG_ACTION_INTERCEPT, priority_label->security_result[0].action); - EXPECT_EQ(TSG_ACTION_INTERCEPT, priority_label->security_result[0].config_id); + free_shaping_result(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, (void *)hited_s_chaining); + stream_bridge_async_data_put(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, NULL); + EXPECT_EQ(nullptr, stream_bridge_async_data_get(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id)); +} - free_policy_label(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id, (void *)priority_label); - stream_bridge_async_data_put(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id, NULL); - EXPECT_EQ(nullptr, stream_bridge_async_data_get(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_POLICY_PRIORITY].id)); +TEST(TSGMaster, ServiceChainingPolicyMultipleNotify) +{ + const struct streaminfo a_stream={0}; + struct Maat_rule_t s_chaining_result[MAX_RESULT_NUM]={0}; + + // first + for(int i=0; isid); + EXPECT_EQ(MAX_RESULT_NUM/2, hited_s_chaining->result_num); + for(int i=0; iresult_num; i++) + { + EXPECT_EQ(TSG_ACTION_S_CHAINING, hited_s_chaining->result[i].action); + EXPECT_EQ(TSG_ACTION_S_CHAINING+i, hited_s_chaining->result[i].config_id); + } + + // second + for(int i=MAX_RESULT_NUM/2; isid); + EXPECT_EQ(MAX_RESULT_NUM, hited_s_chaining->result_num); + for(int i=0; iresult_num; i++) + { + EXPECT_EQ(TSG_ACTION_S_CHAINING, hited_s_chaining->result[i].action); + EXPECT_EQ(TSG_ACTION_S_CHAINING+i, hited_s_chaining->result[i].config_id); + } + + free_shaping_result(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, (void *)hited_s_chaining); + stream_bridge_async_data_put(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id, NULL); + EXPECT_EQ(nullptr, stream_bridge_async_data_get(&a_stream, g_tsg_para.bridge[BRIDGE_TYPE_SERVICE_CHAINING].id)); } int main(int argc, char *argv[]) diff --git a/test/src/gtest_rule.cpp b/test/src/gtest_rule.cpp index e10a961..0d55c05 100644 --- a/test/src/gtest_rule.cpp +++ b/test/src/gtest_rule.cpp @@ -4,19 +4,107 @@ #include "tsg_entry.h" #include "gtest_common.h" +#include "tsg_variable.h" +#include +#include #include -TEST(MasterTest, SetVlan) +int init_fs2_handle(const char *conffile) { - //int ret=set_vlan(NULL, NULL, NULL, 0, NULL, LOG_COMMON_TUNNELS_VLAN_SRC_ID); - //EXPECT_EQ(1, ret); + int value=0,cycle=0; + int output_prometheus=0; + unsigned short fs_server_port=0; + char app_name[128]={0}; + char fs_server_ip[MAX_IPV4_LEN]={0}; + char fs_output_path[128]={0}; + + MESA_load_profile_int_def(conffile, "FIELD_STAT", "CYCLE", &cycle, 30); + MESA_load_profile_short_nodef(conffile, "FIELD_STAT","TELEGRAF_PORT", (short *)&(fs_server_port)); + MESA_load_profile_string_nodef(conffile,"FIELD_STAT","TELEGRAF_IP",fs_server_ip, sizeof(fs_server_ip)); + MESA_load_profile_string_def(conffile,"FIELD_STAT","OUTPUT_PATH",fs_output_path, sizeof(fs_output_path), "tsg_stat.log"); + MESA_load_profile_string_def(conffile,"FIELD_STAT","APP_NAME", app_name, sizeof(app_name), "tsg_master"); + MESA_load_profile_int_def(conffile, "FIELD_STAT", "PROMETHEUS", &output_prometheus, 1); + + g_tsg_para.fs2_handle=FS_create_handle(); + + value=1;//Rewrite + FS_set_para(g_tsg_para.fs2_handle, PRINT_MODE, &value, sizeof(value)); + value=1;//Do not create stat thread + FS_set_para(g_tsg_para.fs2_handle, CREATE_THREAD, &value, sizeof(value)); + + FS_set_para(g_tsg_para.fs2_handle, STAT_CYCLE, &cycle, sizeof(cycle)); + FS_set_para(g_tsg_para.fs2_handle, APP_NAME, app_name, strlen(app_name)+1); + FS_set_para(g_tsg_para.fs2_handle, OUTPUT_DEVICE, fs_output_path, strlen(fs_output_path)+1); + + value=1; + FS_set_para(g_tsg_para.fs2_handle, OUTPUT_PROMETHEUS, &output_prometheus, sizeof(output_prometheus)); + + if(fs_server_port > 0 && strlen(fs_server_ip) > 0) + { + FS_set_para(g_tsg_para.fs2_handle, STATS_SERVER_IP,fs_server_ip, strlen(fs_server_ip)+1); + FS_set_para(g_tsg_para.fs2_handle, STATS_SERVER_PORT,&(fs_server_port), sizeof(fs_server_port)); + } + + value=FS_OUTPUT_INFLUX_LINE; + FS_set_para(g_tsg_para.fs2_handle, STATS_FORMAT, &value, sizeof(value)); + + for(int i=0; iref_cnt); + EXPECT_EQ(TSG_METHOD_TYPE_RATE_LIMIT, user_region->method_type); + + EXPECT_NE(nullptr, user_region->deny); + EXPECT_EQ(TSG_DENY_TYPE_MAX, user_region->deny->type); + EXPECT_EQ(1024, user_region->deny->bps); + + EXPECT_EQ(1, user_region->capture.enabled); + EXPECT_EQ(2000, user_region->capture.depth); + + + security_compile_free(0, &rule, srv_def_large, (MAAT_RULE_EX_DATA *)&user_region, 0, NULL); + EXPECT_EQ(nullptr, user_region); +} + +TEST(TSGMaster, SecurityDenyPolicyGetRatelimitExData) +{ + struct Maat_rule_t rule={2, 0, 1, 0, 16, 0, 0, {0}}; + struct compile_user_region *user_region=(struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, &rule, g_tsg_para.table_id[TABLE_SECURITY_COMPILE]); + EXPECT_NE(nullptr, user_region); + + EXPECT_EQ(2, user_region->ref_cnt); + EXPECT_EQ(TSG_METHOD_TYPE_RATE_LIMIT, user_region->method_type); + + EXPECT_NE(nullptr, user_region->deny); + EXPECT_EQ(TSG_DENY_TYPE_MAX, user_region->deny->type); + EXPECT_EQ(1024, user_region->deny->bps); + + EXPECT_EQ(1, user_region->capture.enabled); + EXPECT_EQ(2000, user_region->capture.depth); +} int main(int argc, char *argv[]) -{ +{ + init_fs2_handle(tsg_conffile); + tsg_rule_init(tsg_conffile, g_tsg_para.logger); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } - diff --git a/test/src/gtest_session_state.cpp b/test/src/gtest_session_state.cpp new file mode 100644 index 0000000..23c8bcd --- /dev/null +++ b/test/src/gtest_session_state.cpp @@ -0,0 +1,186 @@ +#include +#include +#include + +#include +#include +#include "tsg_sync_state.h" + +extern int get_ctrl_pkt(char *buf, int len); + +struct parse_handle test_handle; + +unsigned long long tsg_get_stream_id(struct streaminfo * a_stream) +{ + return 10; +} + +int set_exec_profile_ids( struct streaminfo *a_stream, struct parse_handle *p) +{ + memcpy(&test_handle, p, sizeof(struct parse_handle)); + return 0; +} + +TEST(SESSION_STATE, IllegalPara) +{ + struct streaminfo a_stream = {0}; + struct update_policy policy_array[2]; + memset(policy_array, 0, sizeof(struct update_policy) * 2); + + EXPECT_EQ(-1, tsg_send_session_state(NULL, 0)); + a_stream.opstate = OP_STATE_DATA; + EXPECT_EQ(-1, tsg_send_session_state(&a_stream, OP_STATE_DATA)); + + EXPECT_EQ(-1, tsg_sync_resetall_state(NULL)); + EXPECT_EQ(0, tsg_sync_resetall_state(&a_stream)); + + EXPECT_EQ(-1, tsg_sync_policy_update(&a_stream, policy_array, 0)); + EXPECT_EQ(-1, tsg_sync_policy_update(&a_stream, NULL, 2)); + EXPECT_EQ(-1, tsg_sync_policy_update(NULL, policy_array, 2)); + policy_array[0].type = POLICY_UPDATE_MAX; + EXPECT_EQ(-1, tsg_sync_policy_update(&a_stream, policy_array, 2)); +} + +TEST(SESSION_STATE, OpeningState) +{ + struct streaminfo a_stream = {0}; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + a_stream.opstate = OP_STATE_PENDING; + EXPECT_EQ(0, tsg_send_session_state(&a_stream, OP_STATE_PENDING)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"opening\",\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(SESSION_STATE, CloseState) +{ + struct streaminfo a_stream = {0}; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + a_stream.opstate = OP_STATE_CLOSE; + EXPECT_EQ(0, tsg_send_session_state(&a_stream, OP_STATE_CLOSE)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"closing\",\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(SESSION_STATE, ResetAllState) +{ + struct streaminfo a_stream = {0}; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + EXPECT_EQ(0, tsg_sync_resetall_state(&a_stream)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"resetall\",\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(SESSION_STATE, ActiveStateOnlyServiceChaining) +{ + struct streaminfo a_stream = {0}; + struct update_policy policy_array; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + memset(&policy_array, 0, sizeof(struct update_policy)); + EXPECT_EQ(0, tsg_sync_policy_update(&a_stream, &policy_array, 1)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"active\",\"method\":\"policy_update\",\"params\":{\"service_chaining\":[]},\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(SESSION_STATE, ActiveStateOnlyShaping) +{ + struct streaminfo a_stream = {0}; + struct update_policy policy_array; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + memset(&policy_array, 0, sizeof(struct update_policy)); + policy_array.type = POLICY_UPDATE_SHAPING; + EXPECT_EQ(0, tsg_sync_policy_update(&a_stream, &policy_array, 1)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"active\",\"method\":\"policy_update\",\"params\":{\"shaping\":[]},\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(SESSION_STATE, ActiveStateServiceChainingAndShaping0) +{ + struct streaminfo a_stream = {0}; + struct update_policy policy_array[2]; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + memset(&policy_array, 0, sizeof(struct update_policy) * 2); + policy_array[0].type = POLICY_UPDATE_SHAPING; + EXPECT_EQ(0, tsg_sync_policy_update(&a_stream, policy_array, 2)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"active\",\"method\":\"policy_update\",\"params\":{\"shaping\":[],\"service_chaining\":[]},\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(SESSION_STATE, ActiveStateServiceChainingAndShaping1) +{ + struct streaminfo a_stream = {0}; + struct update_policy policy_array[2]; + char ctrl_pkt_buf[1024]; + int ctrl_pkt_len = 0; + memset(&policy_array, 0, sizeof(struct update_policy) * 2); + policy_array[0].type = POLICY_UPDATE_SHAPING; + policy_array[0].id_num = 3; + policy_array[0].ids[0] = 1; + policy_array[0].ids[1] = 2; + policy_array[0].ids[2] = 3; + policy_array[1].id_num = 3; + policy_array[1].ids[0] = 4; + policy_array[1].ids[1] = 5; + policy_array[1].ids[2] = 6; + EXPECT_EQ(0, tsg_sync_policy_update(&a_stream, policy_array, 2)); + + ctrl_pkt_len = get_ctrl_pkt(ctrl_pkt_buf, 1024); + EXPECT_EQ(ctrl_pkt_len, strlen(ctrl_pkt_buf)+1); + EXPECT_STREQ("{\"state\":\"active\",\"method\":\"policy_update\",\"params\":{\"shaping\":[1,2,3],\"service_chaining\":[4,5,6]},\"session_id\":\"10\",\"tsync\":\"1.0\"}", ctrl_pkt_buf); +} + +TEST(RECEIVE, IllegalPara) +{ + struct streaminfo a_stream = {0}; + const char *payload = "{\"tsync\":\"1.0\",\"session_id\":\"123456789\",\"state\":\"active\",\"method\":\"log_update\",\"params\":{\"sf_profile_ids\":}}"; + const char *payload_ = "{\"tsync\":\"1.0\",\"session_id\":\"123456789\",\"state\":\"active\",\"method\":\"log_update\",\"params\":{\"sf_profile_ids\":[2,3,4,5,6,7]}}"; + + EXPECT_EQ(-1, tsg_recv_control_pkt(&a_stream, payload, strlen(payload))); + EXPECT_EQ(-1, tsg_recv_control_pkt(&a_stream, NULL, strlen(payload))); + EXPECT_EQ(-1, tsg_recv_control_pkt(&a_stream, payload, 0)); + EXPECT_EQ(-1, tsg_recv_control_pkt(NULL, payload_, strlen(payload_))); + EXPECT_EQ(0, tsg_recv_control_pkt(&a_stream, payload_, strlen(payload_))); +} + +#if 0 +TEST(RECEIVE, JsonParse) +{ + struct streaminfo a_stream = {0}; + const char *payload_ = "{\"tsync\":\"1.0\",\"session_id\":\"123456789\",\"state\":\"active\",\"method\":\"log_update\",\"params\":{\"sf_profile_ids\":[2,3,4,5,6,7]}}"; + + EXPECT_EQ(0, tsg_recv_control_pkt(&a_stream, payload_, strlen(payload_))); + + EXPECT_STREQ("1.0", test_handle.tsync); + EXPECT_EQ(123456789, test_handle.session_id); + EXPECT_STREQ("log_update", test_handle.method); + EXPECT_STREQ("active", test_handle.state); + EXPECT_EQ(6, test_handle.sf_ids.id_num); + for (int i = 0; i < 6; i++) + { + EXPECT_EQ(i+2, test_handle.sf_ids.ids[i]); + } +} +#endif + +int main(int argc, char *argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file