#include #include #include #include "kni_entry.h" #include "kni_ratelimit.h" char kni_judge_droppkt(int molecule,int denominator) { int i = random() % denominator; if(i < molecule) { return APP_STATE_DROPPKT; } return APP_STATE_FAWPKT; } int kni_get_ratelimit(int cfg_id,struct kni_ratelimit_info* ratelimit_info,int ser_def_len,char* service_defined) { int i= 0; int molecule_len = 0; char* value = NULL; char* molecule = NULL; char* tmp = NULL; tmp = kni_memncasemem(service_defined, ser_def_len,(char*)"Droprate=", strlen("Droprate=")); if(tmp == NULL) { MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"RATELIMIT","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined); return -1; } value = kni_memncasemem(service_defined, ser_def_len,(char*)"=", strlen("=")); if(value == NULL) { MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"RATELIMIT","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined); return -1; } value = value + 1; if((value != NULL) && (value[0] == 1) && (value[1] == '.')) { ratelimit_info->denominator = 1; ratelimit_info->molecule = 1; return 0; } molecule = kni_memncasemem(service_defined, ser_def_len,(char*)".", strlen(".")); if(molecule == NULL) { MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"RATELIMIT","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined); return -1; } molecule = molecule + 1; if((molecule != NULL)) { molecule_len = strlen(molecule) - 1; ratelimit_info->denominator = 1; for(i=0;i<=molecule_len;i++) { ratelimit_info->denominator *= 10; } ratelimit_info->molecule = atoi(molecule); } return 0; } char kni_process_ratelimit(int thread_seq,const void* a_packet,struct kni_pme_info* pmeinfo) { if((pmeinfo == NULL) || (g_kni_switch_info.ratelimit_switch == 0)) { return APP_STATE_DROPME; } kni_filestate2_set(thread_seq,COLUME_RATELIMIT,0,1); char ret = APP_STATE_GIVEME; struct kni_ratelimit_info* ratelimit_info = &(pmeinfo->ratelimit_info); if((ratelimit_info->denominator == 0) && (ratelimit_info->molecule == 0)) { if(kni_get_ratelimit(pmeinfo->cfg_id,ratelimit_info,pmeinfo->ser_def_len,pmeinfo->service_defined) < 0) { kni_log_debug(RLOG_LV_FATAL,(char*)"RATELIMIT",a_packet,(char*)"kni_get_ratelimit error"); return APP_STATE_DROPME; } kni_log_debug(RLOG_LV_INFO,(char*)"RATELIMIT",a_packet,(char*)"config_id:%d,molecule:%d,denominator:%d",pmeinfo->cfg_id,ratelimit_info->molecule,ratelimit_info->denominator); } ret = kni_judge_droppkt(ratelimit_info->molecule,ratelimit_info->denominator); return ret; }