diff --git a/inc/tsg_rule.h b/inc/tsg_rule.h index 172bfd6..a733b40 100644 --- a/inc/tsg_rule.h +++ b/inc/tsg_rule.h @@ -25,6 +25,7 @@ enum TSG_METHOD_TYPE TSG_METHOD_TYPE_RESET, TSG_METHOD_TYPE_ALERT, TSG_METHOD_TYPE_RATE_LINIT, + TSG_METHOD_TYPE_MIRRORED, TSG_METHOD_TYPE_MAX }; @@ -59,7 +60,7 @@ struct deny_user_region struct monitor_user_region { int enabled; - int mirror_vlan_id; + int vlan_id; }; struct compile_user_region diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b9489c3..24bba12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ 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_traffic_mirror.cpp tsg_send_raw_packet.cpp tsg_action.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_traffic_mirror.cpp tsg_send_raw_packet.cpp tsg_action.cpp tsg_leaky_bucket.cpp) include_directories(${CMAKE_SOURCE_DIR}/inc) include_directories(/opt/MESA/include/MESA/) diff --git a/src/tsg_action.cpp b/src/tsg_action.cpp index e5973b0..fb43e61 100644 --- a/src/tsg_action.cpp +++ b/src/tsg_action.cpp @@ -496,6 +496,17 @@ static unsigned char do_action_reset(const struct streaminfo *a_stream, Maat_rul return APP_STATE_DROPPKT|APP_STATE_DROPME; } +static unsigned char do_action_ratelimit(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region) +{ + struct tcpall_context *context=NULL; + struct leaky_bucket *bucket=create_bucket((double)((user_region->deny->bytes_per_sec)/1000000), user_region->deny->bytes_per_sec, a_stream->threadnum); + tsg_set_bucket_to_tcpall(a_stream, &context, bucket, a_stream->threadnum); + + context=NULL; + + return PROT_STATE_DROPME; +} + static unsigned char do_action_block_mail(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region) { char *payload=NULL; @@ -635,6 +646,9 @@ unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_ case TSG_METHOD_TYPE_REDIRECTION: state=do_action_redirect_xxx( a_stream, p_result, user_region, protocol); break; + case TSG_METHOD_TYPE_RATE_LINIT: + state=do_action_ratelimit(a_stream, p_result, user_region); + break; default: break; } diff --git a/src/tsg_entry.cpp b/src/tsg_entry.cpp index f141fd6..31330db 100644 --- a/src/tsg_entry.cpp +++ b/src/tsg_entry.cpp @@ -193,39 +193,6 @@ static int print_hit_path(const struct streaminfo *a_stream, struct master_conte return 1; } -static int is_xxx_proxy(const struct streaminfo *a_stream) -{ - if(a_stream!=NULL && a_stream->pfather!=NULL) - { - switch(a_stream->pfather->type) - { - case STREAM_TYPE_SOCKS4: - case STREAM_TYPE_SOCKS5: - case STREAM_TYPE_HTTP_PROXY: - return 1; - break; - default: - break; - } - } - - return 0; -} - -static int is_free_context(const struct streaminfo *a_stream, int proxy_flag) -{ - if(proxy_flag==1) - { - int is_proxy=is_xxx_proxy(a_stream); - if(is_proxy!=1) - { - return 0; - } - } - - return 1; -} - static void free_user_item(char *item) { if(item!=NULL) @@ -265,7 +232,7 @@ static int is_hited_allow(struct Maat_rule_t *result, int hit_cnt) return 0; } -static int set_struct_project(const struct streaminfo *a_stream, int project_id, void *data) +int set_struct_project(const struct streaminfo *a_stream, int project_id, void *data) { if(a_stream==NULL || project_id<0) { @@ -288,7 +255,7 @@ static int set_struct_project(const struct streaminfo *a_stream, int project_id, return 1; } -static const void *get_struct_project(const struct streaminfo *a_stream, int project_id) +const void *get_struct_project(const struct streaminfo *a_stream, int project_id) { if(a_stream==NULL || project_id<0) { @@ -314,6 +281,27 @@ static int get_table_id(tsg_protocol_t protocol) return -1; } +static int get_raw_packet_len(const struct streaminfo *a_stream) +{ + int raw_packet_len=0; + + if(a_stream->type==STREAM_TYPE_TCP) + { + if(a_stream->ptcpdetail==NULL || a_stream->ptcpdetail->pdata==NULL || a_stream->ptcpdetail->datalen<=0) + { + return 0; + } + } + + int ret=get_rawpkt_opt_from_streaminfo(a_stream, RAW_PKT_GET_TOT_LEN, &raw_packet_len); + if(ret<0) + { + return 0; + } + + return raw_packet_len; +} + static int get_default_policy(int compile_id, struct Maat_rule_t *result) { struct Maat_rule_t p_result={0}; @@ -339,24 +327,6 @@ static int get_default_policy(int compile_id, struct Maat_rule_t *result) return 0; } -int set_vlan_id_to_project(const struct streaminfo *a_stream, struct tcpall_context **context, int *vlan_id, int vlan_id_num, int thread_seq) -{ - int num=0; - (*context)=(struct tcpall_context *)get_struct_project(a_stream, g_tsg_para.tcpall_project_id); - if(*context==NULL) - { - (*context)=(struct tcpall_context *)dictator_malloc(thread_seq, sizeof(struct tcpall_context)); - memset((*context), 0, sizeof(struct tcpall_context)); - set_struct_project(a_stream, g_tsg_para.tcpall_project_id, (void *)(*context)); - } - - num=MIN(vlan_id_num, MAX_RESULT_NUM-(*context)->vlan_id_num); - memcpy((*context)->vlan_id+(*context)->vlan_id_num, vlan_id, num); - (*context)->vlan_id_num+=num; - - return 0; -} - static int master_send_log(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, int result_num, char *domain, tsg_protocol_t proto, int thread_seq) { tsg_log_t log_msg; @@ -450,11 +420,64 @@ static int tsg_proto_name2flag(char *proto_list, int *flag) static void free_context_label(int thread_seq, void *project_req_value) { + struct master_context *context=(struct master_context *)project_req_value; + if(context!=NULL) + { + if(context->domain!=NULL) + { + dictator_free(thread_seq, (void *)context->domain); + context->domain=NULL; + } + + if(context->result!=NULL) + { + dictator_free(thread_seq, (void *)context->result); + context->result=NULL; + } + + if(context->mid!=NULL) + { + Maat_clean_status(&context->mid); + context->mid=NULL; + } + + dictator_free(thread_seq, (void *)context); + context=NULL; + } + project_req_value=NULL; return ; } +static void free_tcpall_label(int thread_seq, void *project_req_value) +{ + if(project_req_value!=NULL) + { + struct tcpall_context *context=(struct tcpall_context *)project_req_value; + if(context->para!=NULL) + { + switch(context->method_type) + { + case TSG_METHOD_TYPE_MIRRORED: + dictator_free(thread_seq, (void *)(context->vlan)); + context->vlan=NULL; + break; + case TSG_METHOD_TYPE_RATE_LINIT: + destroy_bucket(&(context->bucket), thread_seq); + break; + default: + break; + } + } + + dictator_free(thread_seq, project_req_value); + project_req_value=NULL; + } + + return ; +} + static void free_policy_label(int thread_seq, void *project_req_value) { if(project_req_value!=NULL) @@ -764,40 +787,6 @@ static int scan_fqdn_category_id(Maat_feather_t maat_feather, const struct strea return scan_ret; } -void close_stream_free_context(const struct streaminfo *a_stream, struct master_context *context, int thread_seq) -{ - if(context!=NULL) - { - if(context->hit_cnt>0 && context->result!=NULL) - { - master_send_log(a_stream, context->result, context->hit_cnt, context->domain, context->proto, thread_seq); - } - - if(context->domain!=NULL) - { - dictator_free(thread_seq, (void *)context->domain); - context->domain=NULL; - } - - if(context->result!=NULL) - { - dictator_free(thread_seq, (void *)context->result); - context->result=NULL; - } - - if(context->mid!=NULL) - { - Maat_clean_status(&context->mid); - context->mid=NULL; - } - - dictator_free(thread_seq, (void *)context); - context=NULL; - } - - return ; -} - void set_session_attribute_label(const struct streaminfo *a_stream, enum TSG_ATTRIBUTE_TYPE type, void *value, int thread_seq) { unsigned long long create_time=0; @@ -1327,7 +1316,7 @@ static int app_identify_result_cb(const struct streaminfo *a_stream, int bridge_ } -static int master_deal_pending_state(const struct streaminfo *a_stream, struct master_context *context, struct Maat_rule_t *result, int result_num, void *a_packet) +static int deal_pending_state(const struct streaminfo *a_stream, struct master_context *context, struct Maat_rule_t *result, int result_num, void *a_packet) { int table_id=0; int ret=0,hit_num=0; @@ -1369,7 +1358,7 @@ static int master_deal_pending_state(const struct streaminfo *a_stream, struct m } -static unsigned char tsg_master_entry(const struct streaminfo *a_stream, void **pme, int thread_seq,void *a_packet) +static unsigned char tsg_master_data_entry(const struct streaminfo *a_stream, void **pme, int thread_seq,void *a_packet) { int i=0, ret=0, hit_num=0; unsigned char state=APP_STATE_GIVEME; @@ -1386,10 +1375,6 @@ static unsigned char tsg_master_entry(const struct streaminfo *a_stream, void ** init_context(pme, thread_seq); context=(struct master_context *)*pme; set_struct_project(a_stream, g_tsg_para.context_project_id, *pme); - if(is_xxx_proxy(a_stream)) //sock4/5 - { - context->is_proxy=1; - } } else { @@ -1410,7 +1395,7 @@ static unsigned char tsg_master_entry(const struct streaminfo *a_stream, void ** FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_UDP_LINKS], 0, FS_OP_ADD, 1); } - hit_num+=master_deal_pending_state(a_stream, context, scan_result+hit_num, MAX_RESULT_NUM-hit_num, a_packet); + hit_num+=deal_pending_state(a_stream, context, scan_result+hit_num, MAX_RESULT_NUM-hit_num, a_packet); p_result=tsg_policy_decision_criteria(scan_result, hit_num); if(g_tsg_para.default_compile_switch==1 && p_result==NULL) { @@ -1465,11 +1450,10 @@ static unsigned char tsg_master_entry(const struct streaminfo *a_stream, void ** if((a_stream->opstate==OP_STATE_CLOSE) || (state&APP_STATE_DROPME)==APP_STATE_DROPME) { - context=(struct master_context *)get_struct_project(a_stream, g_tsg_para.context_project_id); - if(context!=NULL && (is_free_context(a_stream, context->is_proxy))) + if(context!=NULL && context->is_log==0 && context->hit_cnt>0 && context->result!=NULL) { - close_stream_free_context(a_stream, context, thread_seq); - set_struct_project(a_stream, g_tsg_para.context_project_id, NULL); // + context->is_log=1; + master_send_log(a_stream, context->result, context->hit_cnt, context->domain, context->proto, thread_seq); } *pme=NULL; } @@ -1477,72 +1461,124 @@ static unsigned char tsg_master_entry(const struct streaminfo *a_stream, void ** return state; } +static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, unsigned char stream_state, void **pme, int thread_seq, const void *a_packet) +{ + int ret=0,hit_num=0; + int vlan_num=0; + int eth_rawpkt_len=0; + scan_status_t scan_mid=NULL; + struct Maat_rule_t *p_result=NULL; + unsigned char state=APP_STATE_GIVEME; + struct Maat_rule_t result[MAX_RESULT_NUM]={0}; + struct mirrored_vlan vlan[MAX_RESULT_NUM]={0}; + struct tcpall_context *context=(struct tcpall_context *)(*pme); + + switch(stream_state) + { + case OP_STATE_PENDING: + hit_num=tsg_scan_nesting_addr(g_tsg_maat_feather, a_stream, PROTO_UNKONWN, &scan_mid, result, MAX_RESULT_NUM); + if(hit_num>0) + { + p_result=tsg_policy_decision_criteria(result, hit_num); + switch(p_result->action) + { + case TSG_ACTION_DENY: + state=tsg_deal_deny_action(a_stream, p_result, PROTO_UNKONWN, ACTION_RETURN_TYPE_APP, a_packet); + master_send_log(a_stream, p_result, hit_num, NULL, PROTO_UNKONWN, thread_seq); + break; + case TSG_ACTION_MONITOR: + vlan_num=tsg_get_vlan_id_by_monitor_rule(g_tsg_maat_feather, result, hit_num, vlan, MAX_RESULT_NUM); + ret=tsg_set_vlan_id_to_tcpall(a_stream, &context, vlan, vlan_num, thread_seq); + if(ret<=0) + { + break; + } + + *pme=(void *)(context); + tsg_send_raw_packet(a_stream, context->vlan, context->vlan_num, thread_seq); + break; + default: + break; + } + } + + Maat_clean_status(&scan_mid); + scan_mid=NULL; + case OP_STATE_DATA: + case OP_STATE_CLOSE: + if(context==NULL || context->para==NULL) + { + break; + } + + switch(context->method_type) + { + case TSG_METHOD_TYPE_MIRRORED: + tsg_send_raw_packet(a_stream, context->vlan, context->vlan_num, thread_seq); + break; + case TSG_METHOD_TYPE_RATE_LINIT: + eth_rawpkt_len=get_raw_packet_len(a_stream); + if(eth_rawpkt_len<=0) + { + break; + } + + ret=is_permit_pass(eth_rawpkt_len, context->bucket, thread_seq); + if(ret==0) + { + state=APP_STATE_GIVEME|APP_STATE_DROPPKT; + } + break; + default: + break; + } + break; + default: + break; + } + + return state; +} + extern "C" unsigned char TSG_MASTER_TCP_ENTRY(const struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet) { - return tsg_master_entry(a_tcp, pme, thread_seq, a_packet); + return tsg_master_data_entry(a_tcp, pme, thread_seq, a_packet); } +struct udp_context +{ + struct master_context *data_entry; + struct tcpall_context *all_entry; +}; + extern "C" unsigned char TSG_MASTER_UDP_ENTRY(const struct streaminfo *a_udp, void **pme, int thread_seq,void *a_packet) { - return tsg_master_entry(a_udp, pme, thread_seq, a_packet); -} + unsigned char state1=APP_STATE_GIVEME; + unsigned char state2=APP_STATE_GIVEME; + struct udp_context *context=(struct udp_context *)(*pme); -extern "C" unsigned char TSG_MASTER_TCPALL_ENTRY(const struct streaminfo *a_tcp, void **pme, int thread_seq, const void *a_packet) -{ - int hit_num=0; - int vlan_id_num=0; - int vlan_id[MAX_RESULT_NUM]={0}; - scan_status_t scan_mid=NULL; - struct Maat_rule_t *p_result=NULL; - unsigned char state=APP_STATE_GIVEME; - struct Maat_rule_t result[MAX_RESULT_NUM]={0}; - struct tcpall_context *context=(struct tcpall_context *)(*pme); - - if(a_tcp->pktstate==OP_STATE_PENDING) + if(*pme==NULL) { - hit_num=tsg_scan_nesting_addr(g_tsg_maat_feather, a_tcp, PROTO_UNKONWN, &scan_mid, result, MAX_RESULT_NUM); - if(hit_num>0) - { - p_result=tsg_policy_decision_criteria(result, hit_num); - switch(p_result->action) - { - case TSG_ACTION_DENY: - state=tsg_deal_deny_action(a_tcp, p_result, PROTO_UNKONWN, ACTION_RETURN_TYPE_APP, a_packet); - master_send_log(a_tcp, p_result, hit_num, NULL, PROTO_UNKONWN, thread_seq); - break; - case TSG_ACTION_MONITOR: - vlan_id_num=tsg_get_vlan_id_by_monitor_rule(g_tsg_maat_feather, result, hit_num, vlan_id, MAX_RESULT_NUM); - if(vlan_id_num<=0) - { - break; - } - - set_vlan_id_to_project(a_tcp, &context, vlan_id, vlan_id_num, thread_seq); - *pme=(void *)(context); - - tsg_send_raw_packet(a_tcp, context->vlan_id, context->vlan_id_num, thread_seq); - break; - default: - break; - } - } - - Maat_clean_status(&scan_mid); - scan_mid=NULL; + *pme=dictator_malloc(thread_seq, sizeof(struct udp_context)); + memset(*pme, 0, sizeof(struct udp_context)); + context=(struct udp_context *)(*pme); } - if(context!=NULL && context->vlan_id_num>0) - { - tsg_send_raw_packet(a_tcp, context->vlan_id, context->vlan_id_num, thread_seq); - } + state1=tsg_master_all_entry(a_udp, a_udp->opstate, (void **)&(context->all_entry), thread_seq, a_packet); + state2=tsg_master_data_entry(a_udp, (void **)&(context->data_entry), thread_seq, a_packet); - if(a_tcp->pktstate==OP_STATE_CLOSE && (*pme)!=NULL) + if(state1&APP_STATE_DROPME || state2&APP_STATE_DROPME || a_udp->opstate==OP_STATE_CLOSE) { dictator_free(thread_seq, *pme); *pme=NULL; } - - return state; + + return (state1|state2); +} + +extern "C" unsigned char TSG_MASTER_TCPALL_ENTRY(const struct streaminfo *a_tcp, void **pme, int thread_seq, const void *a_packet) +{ + return tsg_master_all_entry(a_tcp, a_tcp->pktstate, pme, thread_seq, a_packet); } extern "C" int TSG_MASTER_INIT() @@ -1642,7 +1678,7 @@ extern "C" int TSG_MASTER_INIT() return -1; } - g_tsg_para.tcpall_project_id=project_producer_register("TSG_TCPALL_CONTEXT", PROJECT_VAL_TYPE_STRUCT, free_context_label); + g_tsg_para.tcpall_project_id=project_producer_register("TSG_TCPALL_CONTEXT", PROJECT_VAL_TYPE_STRUCT, free_tcpall_label); if(g_tsg_para.tcpall_project_id<0) { MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "CONTEXT_LABEL", "project_customer_register is error, context label: %s","TSG_TCPALL_CONTEXT"); diff --git a/src/tsg_entry.h b/src/tsg_entry.h index 9989524..b89f460 100644 --- a/src/tsg_entry.h +++ b/src/tsg_entry.h @@ -10,6 +10,7 @@ #include "app_label.h" #include "tsg_label.h" #include "tsg_statistic.h" +#include "tsg_leaky_bucket.h" #include "tsg_traffic_mirror.h" #if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 411) @@ -157,17 +158,32 @@ struct master_context tsg_protocol_t proto; int hit_cnt; int is_esni; - int is_proxy; + int is_log; char *domain; scan_status_t mid; struct Maat_rule_t *result; struct timespec last_scan_time; }; +struct mirrored_vlan +{ + int vlan_id; + int mirrored_pkts; + int mirrored_bytes; + int compile_id_num; + int compile_id[MAX_RESULT_NUM]; +}; + struct tcpall_context { - int vlan_id_num; - int vlan_id[MAX_RESULT_NUM]; + int vlan_num; + enum TSG_METHOD_TYPE method_type; + union + { + struct mirrored_vlan *vlan; + struct leaky_bucket *bucket; + void *para; + }; }; #define _MAX_TABLE_NAME_LEN 64 @@ -300,6 +316,10 @@ int tsg_statistic_init(const char *conffile, void *logger); int tsg_gtp_signaling_hash_init(const char* conffile, void *logger); int tsg_send_raw_packet_init(const char* conffile, void *logger); +int set_struct_project(const struct streaminfo *a_stream, int project_id, void *data); +const void *get_struct_project(const struct streaminfo *a_stream, int project_id); + + //parent_app_name.app_name int tsg_app_id2name(int app_id, char *app_name, int app_name_len, int is_joint_parent); @@ -308,7 +328,8 @@ void ASN_free_data(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp) void subscribe_id_free_data(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp); void app_id_dict_free_data(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp); void http_response_pages_free(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp); -int set_vlan_id_to_project(const struct streaminfo *a_stream, struct tcpall_context **context, int *vlan_id, int vlan_id_num, int thread_seq); +int tsg_set_vlan_id_to_tcpall(const struct streaminfo *a_stream, struct tcpall_context **context, struct mirrored_vlan *vlan_id, int vlan_num, int thread_seq); +int tsg_set_bucket_to_tcpall(const struct streaminfo *a_stream, struct tcpall_context **context, struct leaky_bucket *bucket, int thread_seq); void security_compile_free(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp); struct Maat_rule_t *tsg_policy_decision_criteria(struct streaminfo *a_stream, Maat_rule_t *result, int result_num, int thread_seq); @@ -323,7 +344,7 @@ int tsg_scan_gtp_phone_number_policy(Maat_feather_t maat_feather, const struct s int tsg_get_ip_location(const struct streaminfo *a_stream, int table_id, MAAT_PLUGIN_EX_DATA *client_location, MAAT_PLUGIN_EX_DATA *server_location); int tsg_get_ip_asn(const struct streaminfo *a_stream, int table_id, MAAT_PLUGIN_EX_DATA* client_asn, MAAT_PLUGIN_EX_DATA* server_asn); int tsg_get_subscribe_id(const struct streaminfo *a_stream, struct _subscribe_id_info_t **source_subscribe_id, struct _subscribe_id_info_t **dest_subscribe_id); -int tsg_send_raw_packet(const struct streaminfo *a_stream, int *vlan_id, int vlan_id_num, int thread_seq); -int tsg_get_vlan_id_by_monitor_rule(Maat_feather_t maat_feather, struct Maat_rule_t *result, int result_num, int *vlan_id, int vlan_id_num); +int tsg_send_raw_packet(const struct streaminfo *a_stream, struct mirrored_vlan *vlan, int vlan_num, int thread_seq); +int tsg_get_vlan_id_by_monitor_rule(Maat_feather_t maat_feather, struct Maat_rule_t *result, int result_num, struct mirrored_vlan *vlan, int vlan_num); #endif diff --git a/src/tsg_leaky_bucket.cpp b/src/tsg_leaky_bucket.cpp new file mode 100644 index 0000000..6dbcaf1 --- /dev/null +++ b/src/tsg_leaky_bucket.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include + +struct leaky_bucket +{ + double rate; + int used_size; + int bucket_size; + struct timespec refresh_time; +}; + +void refresh_bucket(struct leaky_bucket * bucket, int thread_seq) +{ + long interval_us=0; + struct timespec end; + clock_gettime(CLOCK_MONOTONIC, &end); + interval_us = (end.tv_sec - bucket->refresh_time.tv_sec)*1000000 + (end.tv_nsec - bucket->refresh_time.tv_nsec)/1000; + + bucket->used_size=bucket->used_size - interval_us*(bucket->rate); + bucket->used_size=(bucket->used_size<0) ? 0 : bucket->used_size; + + bucket->refresh_time=end; + + return ; +} + +int is_permit_pass(int pkt_size, struct leaky_bucket * bucket, int thread_seq) +{ + refresh_bucket(bucket, thread_seq); + if ((bucket->used_size+pkt_size) < bucket->bucket_size) + { + bucket->used_size += pkt_size; + return 1; + } + + return 0; +} + +struct leaky_bucket * create_bucket(double rate, int bucket_size, int thread_seq) +{ + struct leaky_bucket * bucket = (struct leaky_bucket *)dictator_malloc(thread_seq, sizeof(struct leaky_bucket)); + + bucket->rate = rate; + bucket->used_size = 0; + bucket->bucket_size = bucket_size; + + clock_gettime(CLOCK_MONOTONIC, &(bucket->refresh_time)); + + return bucket; +} + +void destroy_bucket(struct leaky_bucket **bucket, int thread_seq) +{ + if(*bucket!=NULL) + { + dictator_free(thread_seq, *bucket); + bucket = NULL; + } + + return ; +} + diff --git a/src/tsg_leaky_bucket.h b/src/tsg_leaky_bucket.h new file mode 100644 index 0000000..42a62da --- /dev/null +++ b/src/tsg_leaky_bucket.h @@ -0,0 +1,10 @@ +#ifndef __TSG_LEAK_BUCKET_H__ +#define __TSG_LEAK_BUCKET_H__ + +struct leaky_bucket; + +struct leaky_bucket *create_bucket(double rate, int bucket_size, int thread_seq); +void destroy_bucket(struct leaky_bucket **bucket, int thread_seq); +int is_permit_pass(int pkt_size, struct leaky_bucket * bucket, int thread_seq); + +#endif diff --git a/src/tsg_rule.cpp b/src/tsg_rule.cpp index 0ecf975..0e8b50f 100644 --- a/src/tsg_rule.cpp +++ b/src/tsg_rule.cpp @@ -96,6 +96,33 @@ static int get_fqdn_len(char *domain) return fqdn_len; } +static int copy_id(int *dst_id, int dst_id_num, int *src_id, int src_id_num) +{ + int num=MIN(dst_id_num, src_id_num); + memcpy(dst_id, src_id, num); + + return num; +} + +static int copy_vlan_id(struct mirrored_vlan *vlan, int vlan_num, int vlan_id, int *compile_id, int compile_id_num) +{ + int i=0; + + for(i=0; imethod_type=TSG_METHOD_TYPE_MIRRORED; user_region->mirror=(struct monitor_user_region *)calloc(1, sizeof(struct monitor_user_region)); get_integer_from_json(mirror_item, "enable", &(user_region->mirror->enabled)); - get_integer_from_json(mirror_item, "mirror_vlan", &(user_region->mirror->mirror_vlan_id)); + get_integer_from_json(mirror_item, "mirror_vlan", &(user_region->mirror->vlan_id)); } return user_region; @@ -2059,12 +2087,12 @@ struct compile_user_region *tsg_get_compile_user_region(const Maat_feather_t maa return ((struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, result, g_tsg_para.table_id[TABLE_SECURITY_COMPILE])); } -int tsg_get_vlan_id_by_monitor_rule(Maat_feather_t maat_feather, struct Maat_rule_t *result, int result_num, int *vlan_id, int vlan_id_num) +int tsg_get_vlan_id_by_monitor_rule(Maat_feather_t maat_feather, struct Maat_rule_t *result, int result_num, struct mirrored_vlan *vlan, int vlan_num) { int i=0,count=0; struct compile_user_region *user_region=NULL; - for(i=0; imirror->mirror_vlan_id; + count+=copy_vlan_id(vlan, count, user_region->mirror->vlan_id, &(result[i].config_id), 1); tsg_free_compile_user_region(&(result[i]), user_region); user_region=NULL; } @@ -2083,3 +2111,65 @@ int tsg_get_vlan_id_by_monitor_rule(Maat_feather_t maat_feather, struct Maat_rul return count; } +int tsg_set_vlan_id_to_tcpall(const struct streaminfo *a_stream, struct tcpall_context **context, struct mirrored_vlan *vlan, int vlan_num, int thread_seq) +{ + int i=0; + + if(vlan==NULL || vlan_num<=0) + { + return 0; + } + + struct tcpall_context * _context=(struct tcpall_context *)get_struct_project(a_stream, g_tsg_para.tcpall_project_id); + if(_context==NULL) + { + _context=(struct tcpall_context *)dictator_malloc(thread_seq, sizeof(struct tcpall_context)); + memset(_context, 0, sizeof(struct tcpall_context)); + _context->method_type=TSG_METHOD_TYPE_MIRRORED; + + _context->vlan=(struct mirrored_vlan *)dictator_malloc(thread_seq, sizeof(struct mirrored_vlan)*MAX_RESULT_NUM); + memset(_context->vlan, 0, sizeof(struct mirrored_vlan)); + + set_struct_project(a_stream, g_tsg_para.tcpall_project_id, (void *)_context); + } + + if(_context->method_type==TSG_METHOD_TYPE_MIRRORED) + { + for(i=0; ivlan_num+=copy_vlan_id(_context->vlan, _context->vlan_num, vlan[i].vlan_id, vlan[i].compile_id, vlan[i].compile_id_num); + } + + (*context)=_context; + return 1; + } + + return 0; +} + +int tsg_set_bucket_to_tcpall(const struct streaminfo *a_stream, struct tcpall_context **context, struct leaky_bucket *bucket, int thread_seq) +{ + struct tcpall_context *_context=(struct tcpall_context *)get_struct_project(a_stream, g_tsg_para.tcpall_project_id); + if(_context==NULL) + { + _context=(struct tcpall_context *)dictator_malloc(thread_seq, sizeof(struct tcpall_context)); + memset(_context, 0, sizeof(struct tcpall_context)); + set_struct_project(a_stream, g_tsg_para.tcpall_project_id, (void *)_context); + } + else + { + if(_context->method_type==TSG_METHOD_TYPE_MIRRORED && _context->vlan) + { + _context->vlan_num=0; + dictator_free(thread_seq, _context->vlan); + _context->vlan=NULL; + } + } + + _context->method_type=TSG_METHOD_TYPE_RATE_LINIT; + _context->bucket=bucket; + + return 0; +} + + diff --git a/src/tsg_send_raw_packet.cpp b/src/tsg_send_raw_packet.cpp index 6fa9b80..8b332d4 100644 --- a/src/tsg_send_raw_packet.cpp +++ b/src/tsg_send_raw_packet.cpp @@ -9,33 +9,38 @@ #include "tsg_entry.h" -static int send_raw_packet(struct traffic_mirror *ttm,char * pkt_ptr,int pkt_len,int *vlan_array,int vlan_num,int thread_seq) +static int send_raw_packet(struct traffic_mirror *ttm,char * pkt_ptr,int pkt_len, struct mirrored_vlan *vlan,int vlan_num,int thread_seq) { - int ret=tsg_traffic_mirror_send_burst(ttm, (char *)pkt_ptr, pkt_len, vlan_array, vlan_num, thread_seq); - if(ret==TRAFFIC_MIRROR_SEND_SUCCESS) + int i=0,ret=0; + for(i=0; ifrag_packet), frag_pkt->pkt_len, vlan_id, vlan_id_num, thread_seq); + send_raw_packet(g_tsg_para.mirror_handle, (char *)(frag_pkt->frag_packet), frag_pkt->pkt_len, vlan, vlan_num, thread_seq); frag_pkt = frag_pkt->next; } break; default: break; } - + return 0; } @@ -74,17 +79,12 @@ int tsg_notify_hited_monitor_result(const struct streaminfo *a_stream, struct Ma return 0; } - int vlan_id_num=0; - int vlan_id[MAX_RESULT_NUM]={0}; + int vlan_num=0; + struct mirrored_vlan vlan[MAX_RESULT_NUM]={0}; struct tcpall_context *context=NULL; - vlan_id_num=tsg_get_vlan_id_by_monitor_rule(g_tsg_maat_feather, result, result_num, vlan_id, MAX_RESULT_NUM); - if(vlan_id_num<=0) - { - return 0; - } - - set_vlan_id_to_project(a_stream, &context, vlan_id, vlan_id_num, thread_seq); + vlan_num=tsg_get_vlan_id_by_monitor_rule(g_tsg_maat_feather, result, result_num, vlan, MAX_RESULT_NUM); + tsg_set_vlan_id_to_tcpall(a_stream, &context, vlan, vlan_num, thread_seq); return 1; } @@ -96,7 +96,7 @@ int tsg_send_raw_packet_init(const char* conffile, void *logger) { return 0; } - + g_tsg_para.mirror_handle=tsg_traffic_mirror_init(conffile, g_tsg_para.logger); if(g_tsg_para.mirror_handle==NULL) {