diff --git a/inc/tsg_rule.h b/inc/tsg_rule.h index af88866..3545288 100644 --- a/inc/tsg_rule.h +++ b/inc/tsg_rule.h @@ -64,7 +64,8 @@ struct Maat_rule_t *tsg_fetch_deny_rule(Maat_rule_t *result, int result_num); enum ACTION_RETURN_TYPE { ACTION_RETURN_TYPE_PROT=0, - ACTION_RETURN_TYPE_APP + ACTION_RETURN_TYPE_APP, + ACTION_RETURN_TYPE_TCPALL }; unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol, enum ACTION_RETURN_TYPE type, const void *user_data); diff --git a/src/tsg_action.cpp b/src/tsg_action.cpp index 124d7bd..00da958 100644 --- a/src/tsg_action.cpp +++ b/src/tsg_action.cpp @@ -1,1006 +1,997 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "MESA/sip.h" -#include -#include - -#include "app_label.h" -#include "tsg_rule.h" -#include "tsg_entry.h" -#include "tsg_statistic.h" -#include "tsg_send_log.h" -#include "tsg_protocol_common.h" - -extern "C" int sendpacket_do_checksum(unsigned char *buf, int protocol, int len); - -static int replace_policy_variable(const struct streaminfo *a_stream, ctemplate::TemplateDictionary *tpl_dict, int policy_id) -{ - char ip_str[128]={0}; - struct session_attribute_label *attr_label=NULL; - - tpl_dict->SetIntValue("tsg_policy_id", policy_id); - - attr_label=(struct session_attribute_label *)project_req_get_struct(a_stream, g_tsg_para.session_attribute_project_id); - if(attr_label!=NULL && attr_label->client_subscribe_id!=NULL) - { - tpl_dict->SetFormattedValue("tsg_subscriber_id", "%s", attr_label->client_subscribe_id->subscribe_id); - } - else - { - tpl_dict->SetFormattedValue("tsg_subscriber_id", "%s", ""); - } - - - switch(a_stream->addr.addrtype) - { - case ADDR_TYPE_IPV4: - inet_ntop(AF_INET, (const void *)&(a_stream->addr.ipv4->saddr), ip_str, sizeof(ip_str)); - tpl_dict->SetFormattedValue("tsg_client_ip", "%s", ip_str); - break; - case ADDR_TYPE_IPV6: - inet_ntop(AF_INET6, (const void *)(a_stream->addr.ipv6->saddr), ip_str, sizeof(ip_str)); - tpl_dict->SetFormattedValue("tsg_client_ip", "%s", ip_str); - break; - default: - tpl_dict->SetFormattedValue("tsg_client_ip", "%s", ""); - break; - } - - return 0; -} - -static int set_drop_stream(const struct streaminfo *a_stream, tsg_protocol_t protocol) -{ - int ret=0, opt_value=1; - MESA_set_stream_opt(a_stream, MSO_DROP_STREAM, (void *)&opt_value, sizeof(opt_value)); - MESA_set_stream_opt(a_stream, MSO_DROP_CURRENT_PKT, (void *)&opt_value, sizeof(opt_value)); - - switch(protocol) - { - case PROTO_MAIL: - case PROTO_POP3: - case PROTO_SMTP: - case PROTO_IMAP: - case PROTO_FTP: - ret=MESA_set_stream_opt(a_stream, MSO_TIMEOUT, (void *)&g_tsg_para.timeout, sizeof(g_tsg_para.timeout)); - if(ret<0) - { - FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SET_TIMOUT_FAILED], 0, FS_OP_ADD, 1); - } - else - { - FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SET_TIMOUT_SUCCESS], 0, FS_OP_ADD, 1); - } - break; - default: - break; - } - - return STATE_DROPME|STATE_DROPPKT; -} - -static int set_dropme_flag(const struct streaminfo *a_stream) -{ - struct master_context *_context=(struct master_context *)get_struct_project(a_stream, g_tsg_para.context_project_id); - if(_context!=NULL) - { - _context->is_dropme=1; - } - - return 0; -} - -static int get_http_header(char *buff, int len, int code, char *user_define) -{ - int used_len=0; - - switch(code) - { - case 200: - used_len=snprintf(buff, len, "HTTP/1.1 %d OK\r\nContent-Type: text/html\r\n\r\n", code); - break; - case 204: - used_len=snprintf(buff, len, "HTTP/1.1 %d No Content\r\nContent-Type: text/html\r\n\r\n", code); - break; - case 403: - used_len=snprintf(buff, len, "HTTP/1.1 %d Forbidden\r\nContent-Type: text/html\r\n\r\n", code); - break; - case 404: - used_len=snprintf(buff, len, "HTTP/1.1 %d Not Found\r\nContent-Type: text/html\r\n\r\n", code); - break; - case 302: - used_len=snprintf(buff, len, "HTTP/1.1 %d Moved Temporarily\r\nContent-Type: text/html\r\nLocation: %s\r\n\r\n", code, user_define); - break; - case 303: - used_len=snprintf(buff, len, "HTTP/1.1 %d See Other\r\nLocation: %s\r\n\r\n", code, user_define); - break; - default: - break; - } - - return used_len; -} - -static int get_tcp_mss_option(const struct streaminfo *a_stream, int type, void *out) -{ - int i=0,ret=0; - int tcp_opt_num=0; - struct tcp_option *tcp_opt=NULL; - - ret=MESA_get_stream_opt(a_stream, MSO_TCP_SYN_OPT, (void *)&tcp_opt, &tcp_opt_num); - if(ret>0) - { - for(i=0; iExpand(&msg_output, &dict_msg); - - used_len=msg_output.length(); - tmp_buff=(char *)dictator_malloc(a_stream->threadnum, (used_len+1)*sizeof(char)); - memcpy(tmp_buff, msg_output.c_str(), used_len); - tmp_buff[used_len]='\0'; - - dict.SetValue("msg", tmp_buff); - - dictator_free(thread_seq, tmp_buff); - tmp_buff=NULL; - } - else - { - dict.SetValue("msg", message); - } - } - else - { - dict.SetValue("msg", "NULL"); - } - - switch (status_code) - { - case 403: - tpl = g_tsg_para.tpl_403; - tpl->Expand(&page_output, &dict); - break; - case 404: - tpl = g_tsg_para.tpl_404; - tpl->Expand(&page_output, &dict); - break; - case 200: - tpl = g_tsg_para.tpl_200; - tpl->Expand(&page_output, &dict); - break; - case 204: - tpl = g_tsg_para.tpl_204; - tpl->Expand(&page_output, &dict); - break; - case 303: - tpl = g_tsg_para.tpl_303; - tpl->Expand(&page_output, &dict); - break; - default: return; - } - - *page_size=page_output.length()+1; - char *_page_buff=(char *)dictator_malloc(thread_seq, (*page_size)*sizeof(char)); - memcpy(_page_buff, page_output.c_str(), *page_size); - *page_buff=_page_buff; - - return ; -} - -static int get_response_pages(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, struct compile_user_region *user_region, char **payload, int thread_seq) -{ - char key[16]={0}; - int payload_len=0; - struct http_response_pages *res_pages=NULL; - - switch(user_region->deny->type) - { - case TSG_DENY_TYPE_MESSAGE: - template_generate(a_stream, user_region->deny->code, p_result->config_id, user_region->deny->message, payload, (size_t *)&payload_len, thread_seq); - return payload_len; - break; - case TSG_DENY_TYPE_PROFILE: - break; - default: - break; - } - - snprintf(key, sizeof(key), "%d", user_region->deny->profile_id); - res_pages=(struct http_response_pages *)Maat_plugin_get_EX_data(g_tsg_maat_feather,g_tsg_para.table_id[TABLE_RESPONSE_PAGES], key); - if(res_pages!=NULL) - { - switch(res_pages->format) - { - case HTTP_RESPONSE_FORMAT_HTML: - *payload=(char *)dictator_malloc(thread_seq, res_pages->content_len); - memcpy(*payload, res_pages->content, res_pages->content_len); - payload_len=res_pages->content_len; - break; - case HTTP_RESPONSE_FORMAT_TEMPLATE: - template_generate(a_stream, user_region->deny->code, p_result->config_id, res_pages->content, payload, (size_t *)&payload_len, thread_seq); - break; - default: - break; - } - - http_response_pages_free(g_tsg_para.table_id[TABLE_RESPONSE_PAGES], (MAAT_PLUGIN_EX_DATA *)&res_pages, 0, NULL); - } - - return payload_len; -} - -static int set_tcp_rst_flags(char *packet, int ip_tcp_hdr_len) -{ - struct tcphdr *tcp=(struct tcphdr *)(packet+(ip_tcp_hdr_len-20)); // tcp header=20 bytes - - tcp->rst=1; - tcp->ack=1; - tcp->psh=0; - tcp->fin=0; - - return 0; -} - -static int set_tcp_fin_flags(char *packet, int ip_tcp_hdr_len) -{ - struct tcphdr *tcp=(struct tcphdr *)(packet+(ip_tcp_hdr_len-20)); // tcp header=20 bytes - - tcp->fin=1; - tcp->ack=1; - tcp->psh=0; - tcp->rst=0; - - return 0; -} - -static int reverse_ip_tcp_header(char *message, int ip_tcp_hdr_len, int v4_or_v6) -{ - int ip_hdr_len=0; - struct tcphdr *tcp=NULL; - struct iphdr *ipv4=NULL; - struct ip6_hdr *ipv6=NULL; - struct in6_addr ipv6_addr; - unsigned short port=0; - unsigned int seq=0,addr=0; - - switch(v4_or_v6) - { - case 4: - ipv4=(struct iphdr *)message; - ip_hdr_len=ipv4->ihl*4; - - addr=ipv4->saddr; - ipv4->saddr=ipv4->daddr; - ipv4->daddr=addr; - break; - case 6: - ipv6=(struct ip6_hdr *)message; - ip_hdr_len=sizeof(struct ip6_hdr); - - memcpy((void *)&ipv6_addr, (void *)&(ipv6->ip6_src), sizeof(struct in6_addr)); - memcpy((void *)&(ipv6->ip6_src), (void *)&(ipv6->ip6_dst), sizeof(struct in6_addr)); - memcpy((void *)&(ipv6->ip6_dst), (void *)&ipv6_addr, sizeof(struct in6_addr)); - break; - default: - return -1; - break; - } - - tcp=(struct tcphdr *)((char *)message+ip_hdr_len); - port=tcp->source; - tcp->source=tcp->dest; - tcp->dest=port; - - seq=tcp->seq; - tcp->seq=tcp->ack_seq; - tcp->ack_seq=seq; - - return 0; -} - -static int copy_ip_tcp_header(const struct streaminfo *a_stream, const void *a_packet, char *message, int *ip_tcp_hdr_len, int *v4_or_v6) -{ - int ip_hdr_len=0,tcp_hdr_len=0; - int tcp_hdr_len_tmp=0; - unsigned short total_len=0; - - struct iphdr *ipv4=NULL; - struct ip6_hdr *ipv6=NULL; - - switch(a_stream->addr.addrtype) - { - case ADDR_TYPE_IPV4: - case __ADDR_TYPE_IP_PAIR_V4: - (*v4_or_v6)=4; - ipv4=(struct iphdr *)a_packet; - ip_hdr_len=ipv4->ihl*4; - total_len=ipv4->tot_len; - break; - case ADDR_TYPE_IPV6: - case __ADDR_TYPE_IP_PAIR_V6: - (*v4_or_v6)=6; - ipv6=(struct ip6_hdr *)a_packet; - ip_hdr_len=sizeof(struct ip6_hdr); - total_len=ipv6->ip6_ctlun.ip6_un1.ip6_un1_plen; - break; - default: - return -1; - break; - } - - memcpy(message, a_packet, ip_hdr_len); - - struct tcphdr * tcp=(struct tcphdr *)((char *)a_packet+ip_hdr_len); - tcp_hdr_len_tmp=tcp->doff*4; - tcp_hdr_len=20; - - memcpy(message+ip_hdr_len, (char *)a_packet+ip_hdr_len, tcp_hdr_len);/*skip tcp option*/ - tcp=(struct tcphdr *)((char *)message+ip_hdr_len); - tcp->doff=5; - - if((*v4_or_v6)==4) - { - tcp->seq=(unsigned int)htonl((unsigned int)ntohl(tcp->seq)+ntohs(total_len)-ip_hdr_len-tcp_hdr_len_tmp); // length of packet payload - } - else - { - tcp->seq=(unsigned int)htonl((unsigned int)ntohl(tcp->seq)+ntohs(total_len)-tcp_hdr_len_tmp); // length of packet payload - } - - (*ip_tcp_hdr_len)=ip_hdr_len+tcp_hdr_len; - - return 0; -} - -int tsg_send_inject_packet(const struct streaminfo *a_stream, enum sapp_inject_opt sio, char *payload, int payload_len, unsigned char raw_route_dir) -{ - int ret=0; - if(payload==NULL || payload_len<=0) - { - return -1; - } - - ret=sapp_inject_pkt((struct streaminfo *)a_stream, sio, payload, payload_len, raw_route_dir); - if(ret<=0) - { - FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INJECT_PKT_FAILED], 0, FS_OP_ADD, 1); - return -1; - } - - FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INJECT_PKT_SUCCESS], 0, FS_OP_ADD, 1); - - return 0; -} - -static int http_send_reponse_packet(const struct streaminfo *a_stream, char *packet, int payload_len, int v4_or_v6, int ip_tcp_hdr_len, int http_hdr_len) -{ - struct iphdr *ipv4=NULL; - struct ip6_hdr *ipv6=NULL; - struct tcphdr *tcp=NULL; - unsigned char raw_route_dir=0; - - tcp=(struct tcphdr *)(packet+(ip_tcp_hdr_len-20)); // tcp header=20 bytes - - if(v4_or_v6==4) - { - ipv4=(struct iphdr *)packet; - ipv4->tot_len=htons(ip_tcp_hdr_len+http_hdr_len+payload_len); - sendpacket_do_checksum((unsigned char *)packet, IPPROTO_TCP, tcp->doff*4 + http_hdr_len+payload_len); - sendpacket_do_checksum((unsigned char *)packet, IPPROTO_IP, ipv4->ihl*4); - } - else - { - ipv6=(struct ip6_hdr *)packet; - ipv6->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(20+http_hdr_len+payload_len); //tcp_hdr_len=20 - sendpacket_do_checksum((unsigned char *)packet, IPPROTO_TCP, tcp->doff*4 + http_hdr_len+payload_len); - } - - raw_route_dir=(a_stream->curdir==DIR_C2S) ? MESA_dir_reverse(a_stream->routedir) : a_stream->routedir; - tsg_send_inject_packet(a_stream, SIO_EXCLUDE_THIS_LAYER_HDR, packet, ip_tcp_hdr_len+http_hdr_len+payload_len, raw_route_dir); - - tcp->seq=htonl(ntohl(tcp->seq)+http_hdr_len+payload_len); - - return ip_tcp_hdr_len+http_hdr_len+payload_len; -} - -static int http_build_response_packet(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, struct compile_user_region *user_region, const void *a_packet) -{ - char *payload=NULL; - char message[1024*64]={0}; - int v4_or_v6=0; - int http_hdr_len=0; - int payload_len=0; - int ip_tcp_hdr_len=0; - int i=0,one_payload_len=0; - int ret=0,send_pkt_len=0; - short max_segment_size=1400; - - ret=copy_ip_tcp_header(a_stream, a_packet, message, &ip_tcp_hdr_len, &v4_or_v6); - if(ret!=0) - { - return 0; - } - - if(a_stream->curdir==DIR_C2S) - { - reverse_ip_tcp_header(message, ip_tcp_hdr_len, v4_or_v6); - } - - http_hdr_len=get_http_header(message+ip_tcp_hdr_len, sizeof(message)-ip_tcp_hdr_len, user_region->deny->code, NULL); - payload_len=get_response_pages(a_stream, p_result, user_region, &payload, a_stream->threadnum); - - set_session_attribute_label(a_stream, TSG_ATTRIBUTE_TYPE_HTTP_ACTION_FILESIZE, (void *)&payload_len, sizeof(int), a_stream->threadnum); - - get_tcp_mss_option(a_stream, TCP_OPT_MSS, (void *)&max_segment_size); - - for(i=0; ithreadnum, payload); - payload=NULL; - } - - set_tcp_fin_flags(message, ip_tcp_hdr_len); - http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //fin - - reverse_ip_tcp_header(message, ip_tcp_hdr_len, v4_or_v6); - http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //fin - - set_tcp_rst_flags(message, ip_tcp_hdr_len); - http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //rst - - reverse_ip_tcp_header(message, ip_tcp_hdr_len, v4_or_v6); - http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //rst - - return send_pkt_len; -} - -static int http_get_redirect_url(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, char *url, int code, char *http_hdr, int http_hdr_len) -{ - int used_len=0; - char *tmp_buff=NULL; - std::string output; - - ctemplate::Template *tpl_303=ctemplate::Template::StringToTemplate(url, strlen(url), ctemplate::DO_NOT_STRIP); - if(tpl_303!=NULL) - { - ctemplate::TemplateDictionary dict_303("url_dict"); //dict is automatically finalized after function returned. - - replace_policy_variable(a_stream, &dict_303, p_result->config_id); - - tpl_303->Expand(&output, &dict_303); - - used_len=output.length(); - tmp_buff=(char *)dictator_malloc(a_stream->threadnum, (used_len+1)*sizeof(char)); - memcpy(tmp_buff, output.c_str(), used_len); - tmp_buff[used_len]='\0'; - - used_len=get_http_header(http_hdr, http_hdr_len, code, tmp_buff); - - dictator_free(a_stream->threadnum, tmp_buff); - tmp_buff=NULL; - } - else - { - used_len=get_http_header(http_hdr, http_hdr_len, code, url); - } - - return used_len; -} - -static unsigned char do_action_reset(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol) -{ - int ret=0,opt_value=0; - struct rst_tcp_para rst_paras={0}; - - if(a_stream->type==STREAM_TYPE_TCP) - { - rst_paras.rst_pkt_num=g_tsg_para.reset.pkt_num; - rst_paras.signature_seed1=g_tsg_para.reset.seed1; - rst_paras.signature_seed2=g_tsg_para.reset.seed2; - rst_paras.th_flags=g_tsg_para.reset.th_flags; - rst_paras.__pad_no_use=0; - rst_paras.dir=g_tsg_para.reset.dir; - ret=MESA_rst_tcp((struct streaminfo *)a_stream, &rst_paras, sizeof(rst_paras)); - if(ret<0) - { - MESA_handle_runtime_log(g_tsg_para.logger, - RLOG_LV_FATAL, - "RST_TCP", - "Send RST failed policy_id: %d service: %d action: %d addr: %s", - p_result->config_id, - p_result->service_id, - (unsigned char)p_result->action, - PRINTADDR(a_stream, g_tsg_para.level) - ); - } - - if(g_tsg_para.reset.remedy==1) - { - opt_value=1; - MESA_set_stream_opt(a_stream, MSO_TCP_RST_REMEDY, (void *)&opt_value, sizeof(opt_value)); - } - - set_drop_stream(a_stream, protocol); - } - - return STATE_DROPPKT|STATE_DROPME; -} - - -static unsigned char do_action_drop(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *a_packet) -{ - if(user_region!=NULL && user_region->deny!=NULL && user_region->deny->type==TSG_DENY_TYPE_SEND_ICMP) - { - send_icmp_unreachable(a_stream); - } - - switch(protocol) - { - case PROTO_DNS: - return STATE_GIVEME|STATE_DROPPKT; - default: - set_drop_stream(a_stream, protocol); - if(g_tsg_para.deploy_mode==DEPLOY_MODE_MIRROR) - { - return do_action_reset(a_stream, p_result, protocol); - } - break; - } - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_tamper(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data, enum ACTION_RETURN_TYPE type) -{ - if(g_tsg_para.feature_tamper==0) - { - do_action_drop(a_stream, p_result, user_region, protocol, user_data); - return STATE_DROPME|STATE_DROPPKT; - } - - 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(a_stream->threadnum, sizeof(struct tcpall_context)); - memset(_context, 0, sizeof(struct tcpall_context)); - set_struct_project(a_stream, g_tsg_para.tcpall_project_id, (void *)_context); - _context->method_type=TSG_METHOD_TYPE_TAMPER; - _context->tamper_count = 0; - } - else - { - _context->method_type = TSG_METHOD_TYPE_TAMPER; - _context->tamper_count = 0; - } - - //当前为tsg_master_plug暂时不处理在tsg_master_all_entry处理,防止命中发两次 - if(ACTION_RETURN_TYPE_APP == type) - { - return STATE_GIVEME|STATE_DROPPKT|STATE_KILL_OTHER; - } - - //TCP这里发送的话,tsg_master_all_entry仍会处理发送,UDP没有这个情况,所以加该判断 - if(a_stream->type == STREAM_TYPE_UDP) - { - send_tamper_xxx(a_stream, &_context->tamper_count, user_data); - } - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_default_xxx(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data) -{ - struct deny_user_region *deny_region=NULL; - - if(user_region->session_para==NULL) - { - return STATE_DROPME|STATE_DROPPKT; - } - - switch(a_stream->type) - { - case STREAM_TYPE_TCP: - deny_region=&(user_region->session_para->tcp); - break; - case STREAM_TYPE_UDP: - deny_region=&(user_region->session_para->udp); - break; - default: - return STATE_DROPME|STATE_DROPPKT; - break; - } - - switch(deny_region->type) - { - case TSG_DENY_TYPE_DEFAULT_RST: - do_action_reset(a_stream, p_result, protocol); - break; - case TSG_DENY_TYPE_SEND_ICMP: - case TSG_DENY_TYPE_DEFAULT_DROP: - struct compile_user_region tmp_user_region; - tmp_user_region.deny=deny_region; - tmp_user_region.capture.enabled=0; - tmp_user_region.capture.depth=0; - tmp_user_region.method_type=TSG_METHOD_TYPE_DROP; - do_action_drop(a_stream, p_result, &tmp_user_region, protocol, user_data); - break; - default: - break; - } - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_ratelimit(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, enum ACTION_RETURN_TYPE type) -{ - struct tcpall_context *context=NULL; - struct leaky_bucket *bucket=create_bucket(user_region->deny->bps, a_stream->threadnum); - - int ret=tsg_set_bucket_to_tcpall(a_stream, &context, bucket, a_stream->threadnum); - if(ret==0) - { - destroy_bucket(&bucket, a_stream->threadnum); - bucket=NULL; - } - - set_dropme_flag(a_stream); - - context=NULL; - - if(type==ACTION_RETURN_TYPE_PROT) - { - return STATE_DROPME; - } - - return STATE_GIVEME|STATE_KILL_OTHER; -} - -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; - unsigned char raw_route_dir=0; - - switch(user_region->deny->code) - { - case 550: - payload=(char *)"550 Mail was identified as spam.\r\n"; - break; - case 551: - payload=(char *)"551 User not local; please try \r\n"; - break; - default: - break; - } - - if(payload!=NULL) - { - raw_route_dir=(a_stream->curdir==DIR_C2S) ? MESA_dir_reverse(a_stream->routedir) : a_stream->routedir; - tsg_send_inject_packet(a_stream, SIO_DEFAULT, payload, strlen(payload), raw_route_dir); - } - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_block_http(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, const void *a_packet) -{ - int opt_value=0; - int send_pkt_len=0; - - switch(user_region->deny->code) - { - case 200: - case 204: - case 403: - case 404: - send_pkt_len=http_build_response_packet(a_stream, p_result, user_region, a_packet); - tsg_set_statistic_opt(send_pkt_len, ((user_region->method_type==TSG_METHOD_TYPE_ALERT) ? OPT_TYPE_ALERT_BYTES : OPT_TYPE_BLOCK_BYTES), a_stream->threadnum); - break; - default: - break; - } - - if(g_tsg_para.reset.remedy==1) - { - opt_value=1; - MESA_set_stream_opt(a_stream, MSO_TCP_RST_REMEDY, (void *)&opt_value, sizeof(opt_value)); - } - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_block_xxx(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *a_packet) -{ - if(user_region==NULL || user_region->deny==NULL) - { - return do_action_drop(a_stream, p_result, user_region, protocol, a_packet); - } - - switch(protocol) - { - case PROTO_HTTP: - return do_action_block_http(a_stream, p_result, user_region, a_packet); - break; - case PROTO_POP3: - case PROTO_IMAP: - case PROTO_SMTP: - case PROTO_MAIL: - return do_action_block_mail(a_stream, p_result, user_region); - break; - default: - break; - } - - set_drop_stream(a_stream, protocol); - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_redirect_http(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region) -{ - int used_http_hdr_len=0; - char http_hdr[1024]={0}; - unsigned char raw_route_dir=0; - - switch(user_region->deny->code) - { - case 302: - case 303: - used_http_hdr_len=http_get_redirect_url(a_stream, p_result, user_region->deny->redirect_url_to, user_region->deny->code, http_hdr, sizeof(http_hdr)); - break; - default: - return STATE_DROPME|STATE_DROPPKT; - break; - } - - raw_route_dir=(a_stream->curdir==DIR_C2S) ? MESA_dir_reverse(a_stream->routedir) : a_stream->routedir; - tsg_send_inject_packet( a_stream, SIO_DEFAULT, http_hdr, used_http_hdr_len, raw_route_dir); - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char do_action_redirect_xxx(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data) -{ - if(user_region==NULL || user_region->deny==NULL) - { - return do_action_drop(a_stream, p_result, user_region, protocol, user_data); - } - - switch(protocol) - { - case PROTO_DNS: - return do_action_redirect_dns(a_stream, p_result, user_region, user_data); - break; - case PROTO_HTTP: - do_action_redirect_http(a_stream, p_result, user_region); - set_drop_stream(a_stream, protocol); - break; - default: - break; - } - - return STATE_DROPME|STATE_DROPPKT; -} - -static unsigned char tsg_do_deny_action(const struct streaminfo *a_stream, struct compile_user_region *user_region, Maat_rule_t *p_result, tsg_protocol_t protocol, enum ACTION_RETURN_TYPE type, const void *user_data) -{ - unsigned char local_state=STATE_GIVEME; - unsigned char state=0; - int method_type=TSG_METHOD_TYPE_RESET; - if(user_region!=NULL) - { - method_type=user_region->method_type; - } - - switch(method_type) - { - case TSG_METHOD_TYPE_DROP: - local_state=do_action_drop(a_stream, p_result, user_region, protocol, user_data); - if(protocol==PROTO_DNS && type==ACTION_RETURN_TYPE_APP) - { - local_state=set_drop_stream(a_stream, protocol); - } - break; - case TSG_METHOD_TYPE_RST: - case TSG_METHOD_TYPE_RESET: - local_state=do_action_reset(a_stream, p_result, protocol); - break; - case TSG_METHOD_TYPE_BLOCK: - case TSG_METHOD_TYPE_ALERT: - local_state=do_action_block_xxx(a_stream, p_result, user_region, protocol, user_data); - break; - case TSG_METHOD_TYPE_REDIRECTION: - local_state=do_action_redirect_xxx( a_stream, p_result, user_region, protocol, user_data); - break; - case TSG_METHOD_TYPE_RATE_LIMIT: - local_state=do_action_ratelimit(a_stream, p_result, user_region, type); - break; - case TSG_METHOD_TYPE_TAMPER: - local_state = do_action_tamper(a_stream, p_result, user_region, protocol, user_data, type); - break; - case TSG_METHOD_TYPE_DEFAULT: - local_state=do_action_default_xxx(a_stream, p_result, user_region, protocol, user_data); - break; - case TSG_METHOD_TYPE_APP_DROP: - if((user_region->deny==NULL) || (user_region->deny->type!=TSG_DENY_TYPE_APP_DROP)) - { - break; - } - - local_state=do_action_drop(a_stream, p_result, user_region, protocol, user_data); - if(protocol==PROTO_DNS && type==ACTION_RETURN_TYPE_APP) - { - local_state=set_drop_stream(a_stream, protocol); - } - - if(user_region->deny->app_para.send_icmp_enable==1) - { - local_state|=send_icmp_unreachable(a_stream); - } - - if(user_region->deny->app_para.send_reset_enable==1) - { - local_state|=do_action_reset(a_stream, p_result, protocol); - } - break; - default: - break; - } - - tsg_notify_hited_monitor_result(a_stream, p_result, 1, a_stream->threadnum); - - if(method_type!=TSG_METHOD_TYPE_DEFAULT && method_type!=TSG_METHOD_TYPE_APP_DROP) - { - struct tcpall_context *context=NULL; - tsg_set_method_to_tcpall(a_stream, &context, (enum TSG_METHOD_TYPE)method_type, a_stream->threadnum); - } - - state=((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_GIVEME : APP_STATE_GIVEME); - state|=((type==ACTION_RETURN_TYPE_PROT) ? (local_state&STATE_DROPME ? PROT_STATE_DROPME : 0) : (local_state&STATE_DROPME ? APP_STATE_DROPME : 0)); - state|=((type==ACTION_RETURN_TYPE_PROT) ? (local_state&STATE_GIVEME ? PROT_STATE_GIVEME: 0) : (local_state&STATE_GIVEME ? APP_STATE_GIVEME: 0)); - state|=((type==ACTION_RETURN_TYPE_PROT) ? (local_state&STATE_DROPPKT ? PROT_STATE_DROPPKT : 0) : (local_state&STATE_DROPPKT ? APP_STATE_DROPPKT: 0)); - state|=((type==ACTION_RETURN_TYPE_PROT) ? (0) : (local_state&STATE_KILL_OTHER ? APP_STATE_KILL_OTHER : 0)); - - return state; -} - -unsigned char tsg_deny_application(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol, int app_id, enum ACTION_RETURN_TYPE type, const void *user_data) -{ - unsigned char state=0; - char app_id_buff[32]={0}; - struct app_id_dict *dict=NULL; - struct compile_user_region app_user_region={0}, *user_region=NULL; - - snprintf(app_id_buff, sizeof(app_id_buff), "%d", app_id); - dict=(struct app_id_dict *)Maat_plugin_get_EX_data(g_tsg_maat_feather, g_tsg_para.table_id[TABLE_APP_ID_DICT], (const char *)app_id_buff); - if(dict==NULL) - { - set_drop_stream(a_stream, protocol); - return ((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_DROPPKT|PROT_STATE_DROPME: APP_STATE_DROPME|APP_STATE_DROPPKT); - } - - user_region=(struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, p_result, g_tsg_para.table_id[TABLE_SECURITY_COMPILE]); - if(user_region!=NULL) - { - app_user_region.capture=user_region->capture; - security_compile_free(g_tsg_para.table_id[TABLE_SECURITY_COMPILE], p_result, NULL, (MAAT_RULE_EX_DATA *)&user_region, 0, NULL); - } - - switch(dict->deny_app_para.type) - { - case TSG_DENY_TYPE_APP_DROP: - app_user_region.method_type=TSG_METHOD_TYPE_APP_DROP; - app_user_region.deny=&(dict->deny_app_para); - break; - case TSG_DENY_TYPE_APP_RATELIMIT: - app_user_region.method_type=TSG_METHOD_TYPE_RATE_LIMIT; - app_user_region.deny=&(dict->deny_app_para); - break; - default: - break; - } - - state=tsg_do_deny_action(a_stream, &app_user_region, p_result, protocol, type, user_data); - app_id_dict_free(g_tsg_para.table_id[TABLE_APP_ID_DICT], (MAAT_PLUGIN_EX_DATA *)&dict, 0, NULL); - - return state; -} - -unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol, enum ACTION_RETURN_TYPE type, const void *user_data) -{ - unsigned char state=0; - struct compile_user_region *user_region=NULL; - - if(p_result->action==TSG_ACTION_BYPASS) - { - return ((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_DROPME : APP_STATE_GIVEME); - } - - user_region=(struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, p_result, g_tsg_para.table_id[TABLE_SECURITY_COMPILE]); - if(user_region==NULL) - { - set_drop_stream(a_stream, protocol); - return ((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_DROPPKT|PROT_STATE_DROPME: APP_STATE_DROPME|APP_STATE_DROPPKT); - } - - if(user_region->method_type==TSG_METHOD_TYPE_APP_DROP) - { - unsigned int app_id=0; - - if(protocol==PROTO_MAIL) - { - app_id=tsg_l7_protocol_name2id(g_tsg_proto_name2id[PROTO_SMTP].name); - } - else - { - app_id=tsg_l7_protocol_name2id(g_tsg_proto_name2id[protocol].name); - } - state=tsg_deny_application(a_stream, p_result, protocol, app_id, ACTION_RETURN_TYPE_APP, user_data); - } - else - { - state=tsg_do_deny_action(a_stream, user_region, p_result, protocol, type, user_data); - } - - security_compile_free(g_tsg_para.table_id[TABLE_SECURITY_COMPILE], p_result, NULL, (MAAT_RULE_EX_DATA *)&user_region, 0, NULL); - - return state; -} - +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "MESA/sip.h" +#include +#include + +#include "app_label.h" +#include "tsg_rule.h" +#include "tsg_entry.h" +#include "tsg_statistic.h" +#include "tsg_send_log.h" +#include "tsg_protocol_common.h" + +extern "C" int sendpacket_do_checksum(unsigned char *buf, int protocol, int len); + +static int replace_policy_variable(const struct streaminfo *a_stream, ctemplate::TemplateDictionary *tpl_dict, int policy_id) +{ + char ip_str[128]={0}; + struct session_attribute_label *attr_label=NULL; + + tpl_dict->SetIntValue("tsg_policy_id", policy_id); + + attr_label=(struct session_attribute_label *)project_req_get_struct(a_stream, g_tsg_para.session_attribute_project_id); + if(attr_label!=NULL && attr_label->client_subscribe_id!=NULL) + { + tpl_dict->SetFormattedValue("tsg_subscriber_id", "%s", attr_label->client_subscribe_id->subscribe_id); + } + else + { + tpl_dict->SetFormattedValue("tsg_subscriber_id", "%s", ""); + } + + + switch(a_stream->addr.addrtype) + { + case ADDR_TYPE_IPV4: + inet_ntop(AF_INET, (const void *)&(a_stream->addr.ipv4->saddr), ip_str, sizeof(ip_str)); + tpl_dict->SetFormattedValue("tsg_client_ip", "%s", ip_str); + break; + case ADDR_TYPE_IPV6: + inet_ntop(AF_INET6, (const void *)(a_stream->addr.ipv6->saddr), ip_str, sizeof(ip_str)); + tpl_dict->SetFormattedValue("tsg_client_ip", "%s", ip_str); + break; + default: + tpl_dict->SetFormattedValue("tsg_client_ip", "%s", ""); + break; + } + + return 0; +} + +static int set_drop_stream(const struct streaminfo *a_stream, tsg_protocol_t protocol) +{ + int ret=0, opt_value=1; + MESA_set_stream_opt(a_stream, MSO_DROP_STREAM, (void *)&opt_value, sizeof(opt_value)); + MESA_set_stream_opt(a_stream, MSO_DROP_CURRENT_PKT, (void *)&opt_value, sizeof(opt_value)); + + switch(protocol) + { + case PROTO_MAIL: + case PROTO_POP3: + case PROTO_SMTP: + case PROTO_IMAP: + case PROTO_FTP: + ret=MESA_set_stream_opt(a_stream, MSO_TIMEOUT, (void *)&g_tsg_para.timeout, sizeof(g_tsg_para.timeout)); + if(ret<0) + { + FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SET_TIMOUT_FAILED], 0, FS_OP_ADD, 1); + } + else + { + FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SET_TIMOUT_SUCCESS], 0, FS_OP_ADD, 1); + } + break; + default: + break; + } + + return STATE_DROPME|STATE_DROPPKT; +} + +static int get_http_header(char *buff, int len, int code, char *user_define) +{ + int used_len=0; + + switch(code) + { + case 200: + used_len=snprintf(buff, len, "HTTP/1.1 %d OK\r\nContent-Type: text/html\r\n\r\n", code); + break; + case 204: + used_len=snprintf(buff, len, "HTTP/1.1 %d No Content\r\nContent-Type: text/html\r\n\r\n", code); + break; + case 403: + used_len=snprintf(buff, len, "HTTP/1.1 %d Forbidden\r\nContent-Type: text/html\r\n\r\n", code); + break; + case 404: + used_len=snprintf(buff, len, "HTTP/1.1 %d Not Found\r\nContent-Type: text/html\r\n\r\n", code); + break; + case 302: + used_len=snprintf(buff, len, "HTTP/1.1 %d Moved Temporarily\r\nContent-Type: text/html\r\nLocation: %s\r\n\r\n", code, user_define); + break; + case 303: + used_len=snprintf(buff, len, "HTTP/1.1 %d See Other\r\nLocation: %s\r\n\r\n", code, user_define); + break; + default: + break; + } + + return used_len; +} + +static int get_tcp_mss_option(const struct streaminfo *a_stream, int type, void *out) +{ + int i=0,ret=0; + int tcp_opt_num=0; + struct tcp_option *tcp_opt=NULL; + + ret=MESA_get_stream_opt(a_stream, MSO_TCP_SYN_OPT, (void *)&tcp_opt, &tcp_opt_num); + if(ret>0) + { + for(i=0; iExpand(&msg_output, &dict_msg); + + used_len=msg_output.length(); + tmp_buff=(char *)dictator_malloc(a_stream->threadnum, (used_len+1)*sizeof(char)); + memcpy(tmp_buff, msg_output.c_str(), used_len); + tmp_buff[used_len]='\0'; + + dict.SetValue("msg", tmp_buff); + + dictator_free(thread_seq, tmp_buff); + tmp_buff=NULL; + } + else + { + dict.SetValue("msg", message); + } + } + else + { + dict.SetValue("msg", "NULL"); + } + + switch (status_code) + { + case 403: + tpl = g_tsg_para.tpl_403; + tpl->Expand(&page_output, &dict); + break; + case 404: + tpl = g_tsg_para.tpl_404; + tpl->Expand(&page_output, &dict); + break; + case 200: + tpl = g_tsg_para.tpl_200; + tpl->Expand(&page_output, &dict); + break; + case 204: + tpl = g_tsg_para.tpl_204; + tpl->Expand(&page_output, &dict); + break; + case 303: + tpl = g_tsg_para.tpl_303; + tpl->Expand(&page_output, &dict); + break; + default: return; + } + + *page_size=page_output.length()+1; + char *_page_buff=(char *)dictator_malloc(thread_seq, (*page_size)*sizeof(char)); + memcpy(_page_buff, page_output.c_str(), *page_size); + *page_buff=_page_buff; + + return ; +} + +static int get_response_pages(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, struct compile_user_region *user_region, char **payload, int thread_seq) +{ + char key[16]={0}; + int payload_len=0; + struct http_response_pages *res_pages=NULL; + + switch(user_region->deny->type) + { + case TSG_DENY_TYPE_MESSAGE: + template_generate(a_stream, user_region->deny->code, p_result->config_id, user_region->deny->message, payload, (size_t *)&payload_len, thread_seq); + return payload_len; + break; + case TSG_DENY_TYPE_PROFILE: + break; + default: + break; + } + + snprintf(key, sizeof(key), "%d", user_region->deny->profile_id); + res_pages=(struct http_response_pages *)Maat_plugin_get_EX_data(g_tsg_maat_feather,g_tsg_para.table_id[TABLE_RESPONSE_PAGES], key); + if(res_pages!=NULL) + { + switch(res_pages->format) + { + case HTTP_RESPONSE_FORMAT_HTML: + *payload=(char *)dictator_malloc(thread_seq, res_pages->content_len); + memcpy(*payload, res_pages->content, res_pages->content_len); + payload_len=res_pages->content_len; + break; + case HTTP_RESPONSE_FORMAT_TEMPLATE: + template_generate(a_stream, user_region->deny->code, p_result->config_id, res_pages->content, payload, (size_t *)&payload_len, thread_seq); + break; + default: + break; + } + + http_response_pages_free(g_tsg_para.table_id[TABLE_RESPONSE_PAGES], (MAAT_PLUGIN_EX_DATA *)&res_pages, 0, NULL); + } + + return payload_len; +} + +static int set_tcp_rst_flags(char *packet, int ip_tcp_hdr_len) +{ + struct tcphdr *tcp=(struct tcphdr *)(packet+(ip_tcp_hdr_len-20)); // tcp header=20 bytes + + tcp->rst=1; + tcp->ack=1; + tcp->psh=0; + tcp->fin=0; + + return 0; +} + +static int set_tcp_fin_flags(char *packet, int ip_tcp_hdr_len) +{ + struct tcphdr *tcp=(struct tcphdr *)(packet+(ip_tcp_hdr_len-20)); // tcp header=20 bytes + + tcp->fin=1; + tcp->ack=1; + tcp->psh=0; + tcp->rst=0; + + return 0; +} + +static int reverse_ip_tcp_header(char *message, int ip_tcp_hdr_len, int v4_or_v6) +{ + int ip_hdr_len=0; + struct tcphdr *tcp=NULL; + struct iphdr *ipv4=NULL; + struct ip6_hdr *ipv6=NULL; + struct in6_addr ipv6_addr; + unsigned short port=0; + unsigned int seq=0,addr=0; + + switch(v4_or_v6) + { + case 4: + ipv4=(struct iphdr *)message; + ip_hdr_len=ipv4->ihl*4; + + addr=ipv4->saddr; + ipv4->saddr=ipv4->daddr; + ipv4->daddr=addr; + break; + case 6: + ipv6=(struct ip6_hdr *)message; + ip_hdr_len=sizeof(struct ip6_hdr); + + memcpy((void *)&ipv6_addr, (void *)&(ipv6->ip6_src), sizeof(struct in6_addr)); + memcpy((void *)&(ipv6->ip6_src), (void *)&(ipv6->ip6_dst), sizeof(struct in6_addr)); + memcpy((void *)&(ipv6->ip6_dst), (void *)&ipv6_addr, sizeof(struct in6_addr)); + break; + default: + return -1; + break; + } + + tcp=(struct tcphdr *)((char *)message+ip_hdr_len); + port=tcp->source; + tcp->source=tcp->dest; + tcp->dest=port; + + seq=tcp->seq; + tcp->seq=tcp->ack_seq; + tcp->ack_seq=seq; + + return 0; +} + +static int copy_ip_tcp_header(const struct streaminfo *a_stream, const void *a_packet, char *message, int *ip_tcp_hdr_len, int *v4_or_v6) +{ + int ip_hdr_len=0,tcp_hdr_len=0; + int tcp_hdr_len_tmp=0; + unsigned short total_len=0; + + struct iphdr *ipv4=NULL; + struct ip6_hdr *ipv6=NULL; + + switch(a_stream->addr.addrtype) + { + case ADDR_TYPE_IPV4: + case __ADDR_TYPE_IP_PAIR_V4: + (*v4_or_v6)=4; + ipv4=(struct iphdr *)a_packet; + ip_hdr_len=ipv4->ihl*4; + total_len=ipv4->tot_len; + break; + case ADDR_TYPE_IPV6: + case __ADDR_TYPE_IP_PAIR_V6: + (*v4_or_v6)=6; + ipv6=(struct ip6_hdr *)a_packet; + ip_hdr_len=sizeof(struct ip6_hdr); + total_len=ipv6->ip6_ctlun.ip6_un1.ip6_un1_plen; + break; + default: + return -1; + break; + } + + memcpy(message, a_packet, ip_hdr_len); + + struct tcphdr * tcp=(struct tcphdr *)((char *)a_packet+ip_hdr_len); + tcp_hdr_len_tmp=tcp->doff*4; + tcp_hdr_len=20; + + memcpy(message+ip_hdr_len, (char *)a_packet+ip_hdr_len, tcp_hdr_len);/*skip tcp option*/ + tcp=(struct tcphdr *)((char *)message+ip_hdr_len); + tcp->doff=5; + + if((*v4_or_v6)==4) + { + tcp->seq=(unsigned int)htonl((unsigned int)ntohl(tcp->seq)+ntohs(total_len)-ip_hdr_len-tcp_hdr_len_tmp); // length of packet payload + } + else + { + tcp->seq=(unsigned int)htonl((unsigned int)ntohl(tcp->seq)+ntohs(total_len)-tcp_hdr_len_tmp); // length of packet payload + } + + (*ip_tcp_hdr_len)=ip_hdr_len+tcp_hdr_len; + + return 0; +} + +int tsg_send_inject_packet(const struct streaminfo *a_stream, enum sapp_inject_opt sio, char *payload, int payload_len, unsigned char raw_route_dir) +{ + int ret=0; + if(payload==NULL || payload_len<=0) + { + return -1; + } + + ret=sapp_inject_pkt((struct streaminfo *)a_stream, sio, payload, payload_len, raw_route_dir); + if(ret<=0) + { + FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INJECT_PKT_FAILED], 0, FS_OP_ADD, 1); + return -1; + } + + FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INJECT_PKT_SUCCESS], 0, FS_OP_ADD, 1); + + return 0; +} + +static int http_send_reponse_packet(const struct streaminfo *a_stream, char *packet, int payload_len, int v4_or_v6, int ip_tcp_hdr_len, int http_hdr_len) +{ + struct iphdr *ipv4=NULL; + struct ip6_hdr *ipv6=NULL; + struct tcphdr *tcp=NULL; + unsigned char raw_route_dir=0; + + tcp=(struct tcphdr *)(packet+(ip_tcp_hdr_len-20)); // tcp header=20 bytes + + if(v4_or_v6==4) + { + ipv4=(struct iphdr *)packet; + ipv4->tot_len=htons(ip_tcp_hdr_len+http_hdr_len+payload_len); + sendpacket_do_checksum((unsigned char *)packet, IPPROTO_TCP, tcp->doff*4 + http_hdr_len+payload_len); + sendpacket_do_checksum((unsigned char *)packet, IPPROTO_IP, ipv4->ihl*4); + } + else + { + ipv6=(struct ip6_hdr *)packet; + ipv6->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(20+http_hdr_len+payload_len); //tcp_hdr_len=20 + sendpacket_do_checksum((unsigned char *)packet, IPPROTO_TCP, tcp->doff*4 + http_hdr_len+payload_len); + } + + raw_route_dir=(a_stream->curdir==DIR_C2S) ? MESA_dir_reverse(a_stream->routedir) : a_stream->routedir; + tsg_send_inject_packet(a_stream, SIO_EXCLUDE_THIS_LAYER_HDR, packet, ip_tcp_hdr_len+http_hdr_len+payload_len, raw_route_dir); + + tcp->seq=htonl(ntohl(tcp->seq)+http_hdr_len+payload_len); + + return ip_tcp_hdr_len+http_hdr_len+payload_len; +} + +static int http_build_response_packet(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, struct compile_user_region *user_region, const void *a_packet) +{ + char *payload=NULL; + char message[1024*64]={0}; + int v4_or_v6=0; + int http_hdr_len=0; + int payload_len=0; + int ip_tcp_hdr_len=0; + int i=0,one_payload_len=0; + int ret=0,send_pkt_len=0; + short max_segment_size=1400; + + ret=copy_ip_tcp_header(a_stream, a_packet, message, &ip_tcp_hdr_len, &v4_or_v6); + if(ret!=0) + { + return 0; + } + + if(a_stream->curdir==DIR_C2S) + { + reverse_ip_tcp_header(message, ip_tcp_hdr_len, v4_or_v6); + } + + http_hdr_len=get_http_header(message+ip_tcp_hdr_len, sizeof(message)-ip_tcp_hdr_len, user_region->deny->code, NULL); + payload_len=get_response_pages(a_stream, p_result, user_region, &payload, a_stream->threadnum); + + set_session_attribute_label(a_stream, TSG_ATTRIBUTE_TYPE_HTTP_ACTION_FILESIZE, (void *)&payload_len, sizeof(int), a_stream->threadnum); + + get_tcp_mss_option(a_stream, TCP_OPT_MSS, (void *)&max_segment_size); + + for(i=0; ithreadnum, payload); + payload=NULL; + } + + set_tcp_fin_flags(message, ip_tcp_hdr_len); + http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //fin + + reverse_ip_tcp_header(message, ip_tcp_hdr_len, v4_or_v6); + http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //fin + + set_tcp_rst_flags(message, ip_tcp_hdr_len); + http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //rst + + reverse_ip_tcp_header(message, ip_tcp_hdr_len, v4_or_v6); + http_send_reponse_packet(a_stream, message, 0, v4_or_v6, ip_tcp_hdr_len, 0); //rst + + return send_pkt_len; +} + +static int http_get_redirect_url(const struct streaminfo *a_stream, struct Maat_rule_t *p_result, char *url, int code, char *http_hdr, int http_hdr_len) +{ + int used_len=0; + char *tmp_buff=NULL; + std::string output; + + ctemplate::Template *tpl_303=ctemplate::Template::StringToTemplate(url, strlen(url), ctemplate::DO_NOT_STRIP); + if(tpl_303!=NULL) + { + ctemplate::TemplateDictionary dict_303("url_dict"); //dict is automatically finalized after function returned. + + replace_policy_variable(a_stream, &dict_303, p_result->config_id); + + tpl_303->Expand(&output, &dict_303); + + used_len=output.length(); + tmp_buff=(char *)dictator_malloc(a_stream->threadnum, (used_len+1)*sizeof(char)); + memcpy(tmp_buff, output.c_str(), used_len); + tmp_buff[used_len]='\0'; + + used_len=get_http_header(http_hdr, http_hdr_len, code, tmp_buff); + + dictator_free(a_stream->threadnum, tmp_buff); + tmp_buff=NULL; + } + else + { + used_len=get_http_header(http_hdr, http_hdr_len, code, url); + } + + return used_len; +} + +static unsigned char do_action_reset(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol) +{ + int ret=0,opt_value=0; + struct rst_tcp_para rst_paras={0}; + + if(a_stream->type==STREAM_TYPE_TCP) + { + rst_paras.rst_pkt_num=g_tsg_para.reset.pkt_num; + rst_paras.signature_seed1=g_tsg_para.reset.seed1; + rst_paras.signature_seed2=g_tsg_para.reset.seed2; + rst_paras.th_flags=g_tsg_para.reset.th_flags; + rst_paras.__pad_no_use=0; + rst_paras.dir=g_tsg_para.reset.dir; + ret=MESA_rst_tcp((struct streaminfo *)a_stream, &rst_paras, sizeof(rst_paras)); + if(ret<0) + { + MESA_handle_runtime_log(g_tsg_para.logger, + RLOG_LV_FATAL, + "RST_TCP", + "Send RST failed policy_id: %d service: %d action: %d addr: %s", + p_result->config_id, + p_result->service_id, + (unsigned char)p_result->action, + PRINTADDR(a_stream, g_tsg_para.level) + ); + } + + if(g_tsg_para.reset.remedy==1) + { + opt_value=1; + MESA_set_stream_opt(a_stream, MSO_TCP_RST_REMEDY, (void *)&opt_value, sizeof(opt_value)); + } + + set_drop_stream(a_stream, protocol); + } + + return STATE_DROPPKT|STATE_DROPME; +} + + +static unsigned char do_action_drop(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *a_packet) +{ + if(user_region!=NULL && user_region->deny!=NULL) + { + send_icmp_unreachable(a_stream); + } + + switch(protocol) + { + case PROTO_DNS: + return STATE_GIVEME|STATE_DROPPKT; + default: + set_drop_stream(a_stream, protocol); + if(g_tsg_para.deploy_mode==DEPLOY_MODE_MIRROR) + { + return do_action_reset(a_stream, p_result, protocol); + } + break; + } + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_tamper(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data, enum ACTION_RETURN_TYPE type) +{ + if(g_tsg_para.feature_tamper==0) + { + do_action_drop(a_stream, p_result, user_region, protocol, user_data); + return STATE_DROPME|STATE_DROPPKT; + } + + 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(a_stream->threadnum, sizeof(struct tcpall_context)); + memset(_context, 0, sizeof(struct tcpall_context)); + set_struct_project(a_stream, g_tsg_para.tcpall_project_id, (void *)_context); + _context->method_type=TSG_METHOD_TYPE_TAMPER; + _context->tamper_count = 0; + } + else + { + _context->method_type = TSG_METHOD_TYPE_TAMPER; + _context->tamper_count = 0; + } + + //当前为tsg_master_plug暂时不处理在tsg_master_all_entry处理,防止命中发两次 + if(ACTION_RETURN_TYPE_APP == type) + { + return STATE_GIVEME|STATE_DROPPKT|STATE_KILL_OTHER; + } + + //TCP这里发送的话,tsg_master_all_entry仍会处理发送,UDP没有这个情况,所以加该判断 + if(a_stream->type == STREAM_TYPE_UDP) + { + send_tamper_xxx(a_stream, &_context->tamper_count, user_data); + } + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_default_xxx(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data) +{ + struct deny_user_region *deny_region=NULL; + + if(user_region->session_para==NULL) + { + return STATE_DROPME|STATE_DROPPKT; + } + + switch(a_stream->type) + { + case STREAM_TYPE_TCP: + deny_region=&(user_region->session_para->tcp); + break; + case STREAM_TYPE_UDP: + deny_region=&(user_region->session_para->udp); + break; + default: + return STATE_DROPME|STATE_DROPPKT; + break; + } + + switch(deny_region->type) + { + case TSG_DENY_TYPE_DEFAULT_RST: + do_action_reset(a_stream, p_result, protocol); + break; + case TSG_DENY_TYPE_DROP: + struct compile_user_region tmp_user_region; + tmp_user_region.deny=deny_region; + tmp_user_region.capture.enabled=0; + tmp_user_region.capture.depth=0; + tmp_user_region.method_type=TSG_METHOD_TYPE_DROP; + do_action_drop(a_stream, p_result, &tmp_user_region, protocol, user_data); + break; + default: + break; + } + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_ratelimit(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, enum ACTION_RETURN_TYPE type) +{ + struct leaky_bucket *bucket=create_bucket(user_region->deny->bps, a_stream->threadnum); + + int ret=set_bucket_to_tcpall(a_stream, bucket, a_stream->threadnum); + if(ret==0) + { + destroy_bucket(&bucket, a_stream->threadnum); + bucket=NULL; + } + + if(type==ACTION_RETURN_TYPE_PROT) + { + return STATE_DROPME; + } + + if(type==ACTION_RETURN_TYPE_APP) + { + return STATE_DROPME|STATE_KILL_OTHER; + } + + return STATE_GIVEME|STATE_KILL_OTHER; +} + +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; + unsigned char raw_route_dir=0; + + switch(user_region->deny->code) + { + case 550: + payload=(char *)"550 Mail was identified as spam.\r\n"; + break; + case 551: + payload=(char *)"551 User not local; please try \r\n"; + break; + default: + break; + } + + if(payload!=NULL) + { + raw_route_dir=(a_stream->curdir==DIR_C2S) ? MESA_dir_reverse(a_stream->routedir) : a_stream->routedir; + tsg_send_inject_packet(a_stream, SIO_DEFAULT, payload, strlen(payload), raw_route_dir); + } + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_block_http(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, const void *a_packet) +{ + int opt_value=0; + int send_pkt_len=0; + + switch(user_region->deny->code) + { + case 200: + case 204: + case 403: + case 404: + send_pkt_len=http_build_response_packet(a_stream, p_result, user_region, a_packet); + tsg_set_statistic_opt(send_pkt_len, ((user_region->method_type==TSG_METHOD_TYPE_ALERT) ? OPT_TYPE_ALERT_BYTES : OPT_TYPE_BLOCK_BYTES), a_stream->threadnum); + break; + default: + break; + } + + if(g_tsg_para.reset.remedy==1) + { + opt_value=1; + MESA_set_stream_opt(a_stream, MSO_TCP_RST_REMEDY, (void *)&opt_value, sizeof(opt_value)); + } + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_block_xxx(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *a_packet) +{ + if(user_region==NULL || user_region->deny==NULL) + { + return do_action_drop(a_stream, p_result, user_region, protocol, a_packet); + } + + switch(protocol) + { + case PROTO_HTTP: + return do_action_block_http(a_stream, p_result, user_region, a_packet); + break; + case PROTO_POP3: + case PROTO_IMAP: + case PROTO_SMTP: + case PROTO_MAIL: + return do_action_block_mail(a_stream, p_result, user_region); + break; + default: + break; + } + + set_drop_stream(a_stream, protocol); + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_redirect_http(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region) +{ + int used_http_hdr_len=0; + char http_hdr[1024]={0}; + unsigned char raw_route_dir=0; + + switch(user_region->deny->code) + { + case 302: + case 303: + used_http_hdr_len=http_get_redirect_url(a_stream, p_result, user_region->deny->redirect_url_to, user_region->deny->code, http_hdr, sizeof(http_hdr)); + break; + default: + return STATE_DROPME|STATE_DROPPKT; + break; + } + + raw_route_dir=(a_stream->curdir==DIR_C2S) ? MESA_dir_reverse(a_stream->routedir) : a_stream->routedir; + tsg_send_inject_packet( a_stream, SIO_DEFAULT, http_hdr, used_http_hdr_len, raw_route_dir); + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char do_action_redirect_xxx(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data) +{ + if(user_region==NULL || user_region->deny==NULL) + { + return do_action_drop(a_stream, p_result, user_region, protocol, user_data); + } + + switch(protocol) + { + case PROTO_DNS: + return do_action_redirect_dns(a_stream, p_result, user_region, user_data); + break; + case PROTO_HTTP: + do_action_redirect_http(a_stream, p_result, user_region); + set_drop_stream(a_stream, protocol); + break; + default: + break; + } + + return STATE_DROPME|STATE_DROPPKT; +} + +static unsigned char tsg_do_deny_action(const struct streaminfo *a_stream, struct compile_user_region *user_region, Maat_rule_t *p_result, tsg_protocol_t protocol, enum ACTION_RETURN_TYPE type, const void *user_data) +{ + unsigned char local_state=STATE_GIVEME; + unsigned char state=0; + int method_type=TSG_METHOD_TYPE_RESET; + if(user_region!=NULL) + { + method_type=user_region->method_type; + } + + switch(method_type) + { + case TSG_METHOD_TYPE_RST: + case TSG_METHOD_TYPE_RESET: + local_state=do_action_reset(a_stream, p_result, protocol); + break; + case TSG_METHOD_TYPE_BLOCK: + case TSG_METHOD_TYPE_ALERT: + local_state=do_action_block_xxx(a_stream, p_result, user_region, protocol, user_data); + break; + case TSG_METHOD_TYPE_REDIRECTION: + local_state=do_action_redirect_xxx( a_stream, p_result, user_region, protocol, user_data); + break; + case TSG_METHOD_TYPE_RATE_LIMIT: + local_state=do_action_ratelimit(a_stream, p_result, user_region, type); + break; + case TSG_METHOD_TYPE_TAMPER: + local_state = do_action_tamper(a_stream, p_result, user_region, protocol, user_data, type); + break; + case TSG_METHOD_TYPE_DEFAULT: + local_state=do_action_default_xxx(a_stream, p_result, user_region, protocol, user_data); + break; + case TSG_METHOD_TYPE_DROP: + case TSG_METHOD_TYPE_APP_DROP: + if(user_region->deny==NULL) + { + break; + } + + if(type!=ACTION_RETURN_TYPE_TCPALL && user_region->deny->after_n_packets>0) + { + set_protocol_to_tcpall(a_stream, protocol, a_stream->threadnum); + set_method_to_tcpall(a_stream, user_region->method_type, a_stream->threadnum); + set_after_n_packet_to_tcpall(a_stream, user_region->deny->after_n_packets, a_stream->threadnum); + tsg_set_policy_result(a_stream, PULL_FW_RESULT, p_result, protocol, a_stream->threadnum); + local_state=((type==ACTION_RETURN_TYPE_PROT) ? (STATE_DROPME) : (STATE_DROPME|STATE_KILL_OTHER)); + break; + } + + local_state=do_action_drop(a_stream, p_result, user_region, protocol, user_data); + if(protocol==PROTO_DNS && type==ACTION_RETURN_TYPE_APP) + { + local_state=set_drop_stream(a_stream, protocol); + } + + if(user_region->deny->drop_para.send_icmp_enable==1) + { + local_state|=send_icmp_unreachable(a_stream); + } + + if(user_region->deny->drop_para.send_reset_enable==1) + { + local_state|=do_action_reset(a_stream, p_result, protocol); + } + break; + default: + break; + } + + tsg_notify_hited_monitor_result(a_stream, p_result, 1, a_stream->threadnum); + + if(method_type!=TSG_METHOD_TYPE_DEFAULT && method_type!=TSG_METHOD_TYPE_APP_DROP) + { + set_method_to_tcpall(a_stream, (enum TSG_METHOD_TYPE)method_type, a_stream->threadnum); + } + + state=((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_GIVEME : APP_STATE_GIVEME); + state|=((type==ACTION_RETURN_TYPE_PROT) ? (local_state&STATE_DROPME ? PROT_STATE_DROPME : 0) : (local_state&STATE_DROPME ? APP_STATE_DROPME : 0)); + state|=((type==ACTION_RETURN_TYPE_PROT) ? (local_state&STATE_GIVEME ? PROT_STATE_GIVEME: 0) : (local_state&STATE_GIVEME ? APP_STATE_GIVEME: 0)); + state|=((type==ACTION_RETURN_TYPE_PROT) ? (local_state&STATE_DROPPKT ? PROT_STATE_DROPPKT : 0) : (local_state&STATE_DROPPKT ? APP_STATE_DROPPKT: 0)); + state|=((type==ACTION_RETURN_TYPE_PROT) ? (0) : (local_state&STATE_KILL_OTHER ? APP_STATE_KILL_OTHER : 0)); + + return state; +} + +unsigned char tsg_deny_application(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol, int app_id, enum ACTION_RETURN_TYPE type, const void *user_data) +{ + unsigned char state=0; + char app_id_buff[32]={0}; + struct app_id_dict *dict=NULL; + struct compile_user_region app_user_region={0}, *user_region=NULL; + + snprintf(app_id_buff, sizeof(app_id_buff), "%d", app_id); + dict=(struct app_id_dict *)Maat_plugin_get_EX_data(g_tsg_maat_feather, g_tsg_para.table_id[TABLE_APP_ID_DICT], (const char *)app_id_buff); + if(dict==NULL) + { + set_drop_stream(a_stream, protocol); + return ((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_DROPPKT|PROT_STATE_DROPME: APP_STATE_DROPME|APP_STATE_DROPPKT); + } + + user_region=(struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, p_result, g_tsg_para.table_id[TABLE_SECURITY_COMPILE]); + if(user_region!=NULL) + { + app_user_region.capture=user_region->capture; + security_compile_free(g_tsg_para.table_id[TABLE_SECURITY_COMPILE], p_result, NULL, (MAAT_RULE_EX_DATA *)&user_region, 0, NULL); + } + + switch(dict->deny_app_para.type) + { + case TSG_DENY_TYPE_APP_DROP: + app_user_region.method_type=TSG_METHOD_TYPE_APP_DROP; + app_user_region.deny=&(dict->deny_app_para); + break; + case TSG_DENY_TYPE_APP_RATELIMIT: + app_user_region.method_type=TSG_METHOD_TYPE_RATE_LIMIT; + app_user_region.deny=&(dict->deny_app_para); + break; + default: + break; + } + + state=tsg_do_deny_action(a_stream, &app_user_region, p_result, protocol, type, user_data); + app_id_dict_free(g_tsg_para.table_id[TABLE_APP_ID_DICT], (MAAT_PLUGIN_EX_DATA *)&dict, 0, NULL); + + return state; +} + +unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol, enum ACTION_RETURN_TYPE type, const void *user_data) +{ + unsigned char state=0; + struct compile_user_region *user_region=NULL; + + if(p_result->action==TSG_ACTION_BYPASS) + { + return ((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_DROPME : APP_STATE_GIVEME); + } + + user_region=(struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, p_result, g_tsg_para.table_id[TABLE_SECURITY_COMPILE]); + if(user_region==NULL) + { + set_drop_stream(a_stream, protocol); + return ((type==ACTION_RETURN_TYPE_PROT) ? PROT_STATE_DROPPKT|PROT_STATE_DROPME: APP_STATE_DROPME|APP_STATE_DROPPKT); + } + + if(user_region->method_type==TSG_METHOD_TYPE_APP_DROP) + { + unsigned int app_id=0; + + if(protocol==PROTO_MAIL) + { + app_id=tsg_l7_protocol_name2id(g_tsg_proto_name2id[PROTO_SMTP].name); + } + else + { + app_id=tsg_l7_protocol_name2id(g_tsg_proto_name2id[protocol].name); + } + state=tsg_deny_application(a_stream, p_result, protocol, app_id, ACTION_RETURN_TYPE_APP, user_data); + } + else + { + state=tsg_do_deny_action(a_stream, user_region, p_result, protocol, type, user_data); + } + + security_compile_free(g_tsg_para.table_id[TABLE_SECURITY_COMPILE], p_result, NULL, (MAAT_RULE_EX_DATA *)&user_region, 0, NULL); + + return state; +} + diff --git a/src/tsg_entry.cpp b/src/tsg_entry.cpp index a34f93e..8efc790 100644 --- a/src/tsg_entry.cpp +++ b/src/tsg_entry.cpp @@ -799,7 +799,7 @@ static void free_tcpall_label(int thread_seq, void *project_req_value) return ; } -static void free_policy_label(int thread_seq, void *project_req_value) +void free_policy_label(int thread_seq, void *project_req_value) { if(project_req_value!=NULL) { @@ -883,7 +883,8 @@ static void copy_result_to_project(const struct streaminfo *a_stream, struct mas priority_label=(struct policy_priority_label *)project_req_get_struct((struct streaminfo *)a_stream, g_tsg_para.priority_project_id); if(priority_label==NULL) { - priority_label=(struct policy_priority_label *)dictator_malloc(thread_seq, sizeof(struct policy_priority_label)); + priority_label=(struct policy_priority_label *)dictator_malloc(thread_seq, sizeof(struct policy_priority_label)); + memset(priority_label, 0, sizeof(struct policy_priority_label)); } else { @@ -898,7 +899,6 @@ static void copy_result_to_project(const struct streaminfo *a_stream, struct mas ); } - memset(priority_label, 0, sizeof(struct policy_priority_label)); priority_label->proto=context->proto; if(context->domain!=NULL) @@ -1186,6 +1186,105 @@ static int set_l7_protocol_label(const struct streaminfo *a_stream, tsg_protocol return 0; } +int set_after_n_packet_to_tcpall(const struct streaminfo *a_stream, int after_n_packets, 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); + } + + _context->hited_para.after_n_packets=after_n_packets; + + return 1; +} + +int set_hited_app_id_to_tcpall(const struct streaminfo *a_stream, int hited_app_id, 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); + } + + _context->hited_para.hited_app_id=hited_app_id; + + return 1; +} + +int set_protocol_to_tcpall(const struct streaminfo *a_stream, tsg_protocol_t protocol, 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); + } + + _context->protocol=protocol; + + return 1; +} + +int set_method_to_tcpall(const struct streaminfo *a_stream, enum TSG_METHOD_TYPE method_type, 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); + } + + switch(_context->method_type) + { + case TSG_METHOD_TYPE_UNKNOWN: + case TSG_METHOD_TYPE_DEFAULT: + case TSG_METHOD_TYPE_MIRRORED: + _context->method_type=method_type; + break; + default: + return 0; + break; + } + + return 1; +} + +int set_bucket_to_tcpall(const struct streaminfo *a_stream, 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); + } + + switch(_context->method_type) + { + case TSG_METHOD_TYPE_RATE_LIMIT: + return 1; + break; + case TSG_METHOD_TYPE_DEFAULT: + case TSG_METHOD_TYPE_UNKNOWN: + break; + default: + return 0; + break; + } + + _context->method_type=TSG_METHOD_TYPE_RATE_LIMIT; + _context->bucket=bucket; + + return 1; +} + void set_session_attribute_label(const struct streaminfo *a_stream, enum TSG_ATTRIBUTE_TYPE type, void *value, int value_len, int thread_seq) { unsigned long long create_time=0; @@ -1707,10 +1806,8 @@ int scan_application_id_and_properties(const struct streaminfo *a_stream, struct static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, struct master_context *context, struct Maat_rule_t *result, int hit_num, const void *a_packet) { - int ret=0; Maat_rule_t *p_result=NULL; unsigned char state=APP_STATE_GIVEME; - struct tcpall_context *tmp_tcpall_context=NULL; p_result=tsg_policy_decision_criteria(result, hit_num); if(p_result!=NULL) @@ -1725,24 +1822,9 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, { context->hited_para.hited_app_id=tsg_l7_protocol_name2id(g_tsg_proto_name2id[context->proto].name); } - - if(context->hited_para.after_n_packets>0) - { - ret=tsg_set_method_to_tcpall(a_stream, &tmp_tcpall_context, TSG_METHOD_TYPE_APP_DROP, a_stream->threadnum); - if(ret>0) - { - tmp_tcpall_context->hited_para=context->hited_para; - } - - copy_result_to_project(a_stream, context, p_result, PULL_FW_RESULT, a_stream->threadnum); - context->is_dropme=1; //only tcp - state=APP_STATE_KILL_OTHER|APP_STATE_GIVEME; - break; - } - else - { - state=tsg_deny_application(a_stream, p_result, context->proto, context->hited_para.hited_app_id, ACTION_RETURN_TYPE_APP, a_packet); - } + + set_hited_app_id_to_tcpall(a_stream, context->hited_para.hited_app_id, a_stream->threadnum); + state=tsg_deny_application(a_stream, p_result, context->proto, context->hited_para.hited_app_id, ACTION_RETURN_TYPE_APP, a_packet); } else { @@ -1779,7 +1861,7 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_BYPASS], 0, FS_OP_ADD, 1); state=APP_STATE_GIVEME|APP_STATE_KILL_OTHER; - tsg_set_method_to_tcpall(a_stream, &tmp_tcpall_context, TSG_METHOD_TYPE_ALLOW, a_stream->threadnum); + set_method_to_tcpall(a_stream, TSG_METHOD_TYPE_ALLOW, a_stream->threadnum); break; case TSG_ACTION_INTERCEPT: if(is_intercept_exclusion(a_stream, p_result, context->domain, a_stream->threadnum)) @@ -1792,7 +1874,7 @@ static unsigned char master_deal_scan_result(const struct streaminfo *a_stream, 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; - tsg_set_method_to_tcpall(a_stream, &tmp_tcpall_context, TSG_METHOD_TYPE_UNKNOWN, a_stream->threadnum); + set_method_to_tcpall(a_stream, TSG_METHOD_TYPE_UNKNOWN, a_stream->threadnum); break; default: break; @@ -1890,7 +1972,7 @@ static int app_identify_result_cb(const struct streaminfo *a_stream, int bridge_ return 0; } - master_deal_scan_result(a_stream, context, scan_result, hit_num, NULL); + context->sync_cb_state=master_deal_scan_result(a_stream, context, scan_result, hit_num, NULL); return 0; } @@ -1916,7 +1998,7 @@ static int session_flags_identify_result_cb(const struct streaminfo *a_stream, i int hit_num=tsg_scan_session_flags(g_tsg_maat_feather, a_stream, scan_result, MAX_RESULT_NUM, &context->mid, g_tsg_para.table_id[TABLE_SESSION_FLAGS], context->session_flag, a_stream->threadnum); - master_deal_scan_result(a_stream, context, scan_result, hit_num, NULL); + context->sync_cb_state=master_deal_scan_result(a_stream, context, scan_result, hit_num, NULL); return 0; } @@ -2027,6 +2109,21 @@ static unsigned char tsg_master_data_entry(const struct streaminfo *a_stream, vo context->deal_pkt_num++; break; case OP_STATE_DATA: + if(context->sync_cb_state&APP_STATE_KILL_OTHER || context->sync_cb_state&APP_STATE_DROPPKT) + { + if(a_stream->type==STREAM_TYPE_TCP) //tcpall + { + state=context->sync_cb_state|APP_STATE_DROPME; + break; + } + + if(a_stream->type==STREAM_TYPE_UDP) // allow, Deny(after drop N packets) + { + state=context->sync_cb_state&(~(APP_STATE_DROPME)); + break; + } + } + if(context->is_app_link==FLAG_FALSE && (context->deal_pkt_num++) == (g_tsg_para.identify_app_max_pkt_num+1)) { unknown_result.app_id_num=1; @@ -2089,11 +2186,6 @@ static unsigned char tsg_master_data_entry(const struct streaminfo *a_stream, vo default: break; } - - if(context->is_dropme==1 && a_stream->type==STREAM_TYPE_TCP) - { - state=APP_STATE_KILL_OTHER|APP_STATE_DROPME; - } if((a_stream->opstate==OP_STATE_CLOSE) || (state&APP_STATE_DROPME)==APP_STATE_DROPME) { @@ -2117,7 +2209,6 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns unsigned char state=APP_STATE_GIVEME; struct identify_info tmp_identify_info; struct Maat_rule_t result[MAX_RESULT_NUM]={0}; - struct master_context *data_context=NULL; struct tcpall_context *all_context=(struct tcpall_context *)(*pme); if(stream_state==OP_STATE_PENDING && all_context->method_type!=TSG_METHOD_TYPE_ALLOW) @@ -2135,7 +2226,7 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns 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); + state=tsg_deal_deny_action(a_stream, p_result, PROTO_UNKONWN, ACTION_RETURN_TYPE_TCPALL, a_packet); master_send_log(a_stream, p_result, 1, NULL, thread_seq); break; case TSG_ACTION_MONITOR: @@ -2178,10 +2269,11 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns if(get_default_policy(g_tsg_para.default_compile_id, &result[0])) { - state=tsg_deal_deny_action(a_stream, &result[0], PROTO_UNKONWN, ACTION_RETURN_TYPE_APP, a_packet); + state=tsg_deal_deny_action(a_stream, &result[0], PROTO_UNKONWN, ACTION_RETURN_TYPE_TCPALL, a_packet); master_send_log(a_stream, &result[0], 1, NULL, thread_seq); } break; + case TSG_METHOD_TYPE_DROP: case TSG_METHOD_TYPE_APP_DROP: if((all_context->hited_para.after_n_packets-- > 0) || stream_state==OP_STATE_CLOSE) { @@ -2191,15 +2283,8 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns ret=tsg_pull_policy_result((struct streaminfo *)a_stream,PULL_FW_RESULT, &result[0], 1, &tmp_identify_info); if(ret>0) { - data_context=(struct master_context *)get_struct_project(a_stream, g_tsg_para.context_project_id); - state=tsg_deny_application(a_stream, - &result[0], - (data_context==NULL ? PROTO_UNKONWN : data_context->proto), - all_context->hited_para.hited_app_id, - ACTION_RETURN_TYPE_APP, - a_packet - ); - master_send_log(a_stream, &result[0], 1, data_context, thread_seq); + state=tsg_deny_application(a_stream, &result[0], all_context->protocol, all_context->hited_para.hited_app_id, ACTION_RETURN_TYPE_TCPALL, a_packet); + //master_send_log(a_stream, &result[0], 1, data_context, thread_seq); } break; default: @@ -2214,12 +2299,6 @@ extern "C" unsigned char TSG_MASTER_TCP_ENTRY(const struct streaminfo *a_tcp, vo 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) { unsigned char state1=APP_STATE_GIVEME; diff --git a/src/tsg_entry.h b/src/tsg_entry.h index 13b9c1d..686dc36 100644 --- a/src/tsg_entry.h +++ b/src/tsg_entry.h @@ -260,10 +260,9 @@ struct master_context { unsigned char is_esni; unsigned char is_log; - unsigned char is_dropme; unsigned char deal_pkt_num; unsigned char is_app_link; - unsigned char padding; + unsigned char sync_cb_state; unsigned short timeout; tsg_protocol_t proto; int hit_cnt; @@ -287,6 +286,7 @@ struct tcpall_context { int set_latency_flag; enum TSG_METHOD_TYPE method_type; + tsg_protocol_t protocol; union { struct leaky_bucket *bucket; @@ -297,6 +297,12 @@ struct tcpall_context }; }; +struct udp_context +{ + struct master_context *data_entry; + struct tcpall_context *all_entry; +}; + struct reset_argv { int pkt_num; @@ -474,8 +480,10 @@ void tunnel_endpoint_free(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void void http_response_pages_free(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp); void dns_profile_records_free(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp); void set_session_attribute_label(const struct streaminfo *a_stream, enum TSG_ATTRIBUTE_TYPE type, void *value, int value_len, int thread_seq); -int tsg_set_method_to_tcpall(const struct streaminfo *a_stream, struct tcpall_context **context, enum TSG_METHOD_TYPE method_type, 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); +int set_method_to_tcpall(const struct streaminfo *a_stream, enum TSG_METHOD_TYPE method_type, int thread_seq); +int set_protocol_to_tcpall(const struct streaminfo *a_stream, tsg_protocol_t protocol, int thread_seq); +int set_bucket_to_tcpall(const struct streaminfo *a_stream, struct leaky_bucket *bucket, int thread_seq); +int set_after_n_packet_to_tcpall(const struct streaminfo *a_stream, int after_n_packets, 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); @@ -487,6 +495,8 @@ int tsg_scan_subscribe_id_policy(Maat_feather_t maat_feather, const struct strea int tsg_get_umts_user_info(const struct streaminfo *a_stream, struct umts_user_info **user_info); struct umts_user_info *tsg_get_umts_user_info_form_redis(unsigned int teid); +void free_policy_label(int thread_seq, void *project_req_value); +int tsg_set_policy_result(const struct streaminfo *a_stream, PULL_RESULT_TYPE result_type, struct Maat_rule_t *p_result, tsg_protocol_t proto, int thread_seq); int tsg_scan_gtp_apn_policy(Maat_feather_t maat_feather, const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, scan_status_t *mid, char *apn, int thread_seq); int tsg_scan_gtp_imsi_policy(Maat_feather_t maat_feather, const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, scan_status_t *mid, char *imsi, int thread_seq); int tsg_scan_gtp_phone_number_policy(Maat_feather_t maat_feather, const struct streaminfo *a_stream, struct Maat_rule_t *result, int result_num, scan_status_t *mid, char *phone_number, int thread_seq); diff --git a/src/tsg_protocol_common.h b/src/tsg_protocol_common.h index 1361837..a246619 100644 --- a/src/tsg_protocol_common.h +++ b/src/tsg_protocol_common.h @@ -20,9 +20,8 @@ enum TSG_DENY_TYPE TSG_DENY_TYPE_REDIRECT_TO, TSG_DENY_TYPE_REDIRECT_URL, TSG_DENY_TYPE_REDIRECT_RECORD, - TSG_DENY_TYPE_SEND_ICMP, + TSG_DENY_TYPE_DROP, TSG_DENY_TYPE_DEFAULT_RST, - TSG_DENY_TYPE_DEFAULT_DROP, TSG_DENY_TYPE_APP_DROP, TSG_DENY_TYPE_APP_RATELIMIT, TSG_DENY_TYPE_MAX @@ -79,7 +78,7 @@ struct packet_capture int depth; }; -struct app_action_para +struct action_para { int send_reset_enable; int send_icmp_enable; @@ -101,8 +100,7 @@ struct deny_user_region struct dns_user_region *records; int profile_id; int bps; - int send_icmp_enable; - struct app_action_para app_para; + struct action_para drop_para; void *para; }; }; diff --git a/src/tsg_rule.cpp b/src/tsg_rule.cpp index 9ead157..2e380f7 100644 --- a/src/tsg_rule.cpp +++ b/src/tsg_rule.cpp @@ -650,9 +650,9 @@ static int parse_deny_action(char *deny_action_str, struct deny_user_region *den { case TSG_METHOD_TYPE_DROP: deny_app_para->type=TSG_DENY_TYPE_APP_DROP; - get_integer_from_json(app_para, "send_tcp_reset", &(deny_app_para->app_para.send_reset_enable)); + get_integer_from_json(app_para, "send_tcp_reset", &(deny_app_para->drop_para.send_reset_enable)); get_integer_from_json(app_para, "after_n_packets", &(deny_app_para->after_n_packets)); - get_integer_from_json(app_para, "send_icmp_unreachable", &(deny_app_para->app_para.send_icmp_enable)); + get_integer_from_json(app_para, "send_icmp_unreachable", &(deny_app_para->drop_para.send_icmp_enable)); break; case TSG_METHOD_TYPE_RATE_LIMIT: deny_app_para->type=TSG_DENY_TYPE_APP_RATELIMIT; @@ -980,16 +980,10 @@ static int parse_default_para(cJSON *deny_user_region_object, struct compile_use get_integer_from_json(tcp_session_item, "after_n_packets", &(user_region->session_para->tcp.after_n_packets)); break; case TSG_METHOD_TYPE_DROP: + user_region->session_para->tcp.type=TSG_DENY_TYPE_DROP; get_integer_from_json(tcp_session_item, "after_n_packets", &(user_region->session_para->tcp.after_n_packets)); - get_integer_from_json(tcp_session_item, "send_icmp_unreachable", &(user_region->session_para->tcp.send_icmp_enable)); - if(user_region->session_para->tcp.send_icmp_enable==1) - { - user_region->session_para->tcp.type=TSG_DENY_TYPE_SEND_ICMP; - } - else - { - user_region->session_para->tcp.type=TSG_DENY_TYPE_DEFAULT_DROP; - } + get_integer_from_json(tcp_session_item, "send_icmp_unreachable", &(user_region->session_para->tcp.drop_para.send_icmp_enable)); + get_integer_from_json(tcp_session_item, "send_tcp_reset", &(user_region->session_para->tcp.drop_para.send_reset_enable)); break; default: break; @@ -1000,17 +994,9 @@ static int parse_default_para(cJSON *deny_user_region_object, struct compile_use method_item=cJSON_GetObjectItem(udp_session_item, "method"); if(method_item!=NULL) { - user_region->session_para->udp.type=TSG_DENY_TYPE_DEFAULT_DROP; + user_region->session_para->udp.type=TSG_DENY_TYPE_DROP; get_integer_from_json(udp_session_item, "after_n_packets", &(user_region->session_para->udp.after_n_packets)); - get_integer_from_json(udp_session_item, "send_icmp_unreachable", &(user_region->session_para->udp.send_icmp_enable)); - if(user_region->session_para->udp.send_icmp_enable==1) - { - user_region->session_para->udp.type=TSG_DENY_TYPE_SEND_ICMP; - } - else - { - user_region->session_para->udp.type=TSG_DENY_TYPE_DEFAULT_DROP; - } + get_integer_from_json(udp_session_item, "send_icmp_unreachable", &(user_region->session_para->udp.drop_para.send_icmp_enable)); } return 1; @@ -1139,14 +1125,12 @@ static struct compile_user_region *parse_deny_user_region(cJSON *deny_user_regio user_region->deny->type=TSG_DENY_TYPE_MAX; get_integer_from_json(deny_user_region_object, "bps", &(user_region->deny->bps)); break; - case TSG_METHOD_TYPE_DROP: + case TSG_METHOD_TYPE_DROP: user_region->deny=(struct deny_user_region *)calloc(1, sizeof(struct deny_user_region)); - ret=get_integer_from_json(deny_user_region_object, "send_icmp_unreachable", &(user_region->deny->send_icmp_enable)); - if(ret==1) - { - user_region->deny->type=TSG_DENY_TYPE_SEND_ICMP; - break; - } + user_region->deny->type=TSG_DENY_TYPE_DROP; + get_integer_from_json(deny_user_region_object, "send_icmp_unreachable", &(user_region->deny->drop_para.send_icmp_enable)); + get_integer_from_json(deny_user_region_object, "send_tcp_reset", &(user_region->deny->drop_para.send_reset_enable)); + get_integer_from_json(deny_user_region_object, "after_n_packets", &(user_region->deny->after_n_packets)); break; case TSG_METHOD_TYPE_APP_DROP: break; @@ -2250,6 +2234,51 @@ static int get_fqdn_category_id(Maat_feather_t maat_feather, int table_id, char return 0; } +int tsg_set_policy_result(const struct streaminfo *a_stream, PULL_RESULT_TYPE result_type, struct Maat_rule_t *p_result, tsg_protocol_t proto, int thread_seq) +{ + struct policy_priority_label *priority_label=NULL; + + priority_label=(struct policy_priority_label *)project_req_get_struct((struct streaminfo *)a_stream, g_tsg_para.priority_project_id); + if(priority_label==NULL) + { + priority_label=(struct policy_priority_label *)dictator_malloc(thread_seq, sizeof(struct policy_priority_label)); + memset(priority_label, 0, sizeof(struct policy_priority_label)); + } + + + priority_label->proto=proto; + priority_label->result_num=1; + priority_label->result_type=result_type; + memcpy(priority_label->result, p_result, sizeof(struct Maat_rule_t)); + + int ret=project_req_add_struct((struct streaminfo *)a_stream, g_tsg_para.priority_project_id, (void *)priority_label); + if(ret<0) + { + free_policy_label(thread_seq, (void *)priority_label); + MESA_handle_runtime_log(g_tsg_para.logger, + RLOG_LV_FATAL, + "PROJECT_ADD", + "Add policy_priority_label failed, policy, policy_id: %d action: %d addr: %s", + priority_label->result[0].config_id, + (unsigned char)priority_label->result[0].action, + PRINTADDR(a_stream, g_tsg_para.level) + ); + return -1; + } + + MESA_handle_runtime_log(g_tsg_para.logger, + RLOG_LV_DEBUG, + "COPY_RESULT", + "Hit policy, policy_id: %d action: %d addr: %s", + priority_label->result[0].config_id, + (unsigned char)priority_label->result[0].action, + PRINTADDR(a_stream, g_tsg_para.level) + ); + + return 0; +} + + int tsg_pull_policy_result(struct streaminfo *a_stream, PULL_RESULT_TYPE pull_result_type, Maat_rule_t*result, int result_num, struct identify_info *identify_info) { int num=0; @@ -3308,63 +3337,6 @@ int tsg_notify_hited_monitor_result(const struct streaminfo *a_stream, struct Ma return 1; } -int tsg_set_method_to_tcpall(const struct streaminfo *a_stream, struct tcpall_context **context, enum TSG_METHOD_TYPE method_type, 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); - } - - switch(_context->method_type) - { - case TSG_METHOD_TYPE_UNKNOWN: - case TSG_METHOD_TYPE_DEFAULT: - case TSG_METHOD_TYPE_MIRRORED: - _context->method_type=method_type; - *context=_context; - break; - default: - return 0; - break; - } - - return 1; -} - -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); - } - - switch(_context->method_type) - { - case TSG_METHOD_TYPE_RATE_LIMIT: - *context=_context; - return 1; - break; - case TSG_METHOD_TYPE_DEFAULT: - case TSG_METHOD_TYPE_UNKNOWN: - break; - default: - return 0; - break; - } - - _context->method_type=TSG_METHOD_TYPE_RATE_LIMIT; - _context->bucket=bucket; - *context=_context; - - return 1; -} - char *tsg_get_column_string_value(const char* line, int column_seq) { int ret=0; diff --git a/src/tsg_send_log.cpp b/src/tsg_send_log.cpp index 3e266e2..91cce87 100644 --- a/src/tsg_send_log.cpp +++ b/src/tsg_send_log.cpp @@ -1933,9 +1933,12 @@ int load_log_common_field(const char *filename, id2field_t *id2field, struct top case TLD_TYPE_FILE: case TLD_TYPE_LONG: case TLD_TYPE_STRING: - id2field[id].type = tld_type[i].type; - id2field[id].id = id; - memcpy(id2field[id].name, field_name, strlen(field_name)); + if(id