/* * quic_entry.cpp * * Created on: 2021-11-09 * Author: liuxueli */ #include #include #include #include #include "quic.h" #include "quic_entry.h" #include "quic_process.h" #include "quic_deprotection.h" struct quic_param g_quic_param; const char *g_quic_proto_conffile="./conf/quic/main.conf"; const char *g_quic_regionname_conffile="./conf/quic/quic.conf"; #ifdef __cplusplus extern "C" { #endif #define GIT_VERSION_CATTER(v) __attribute__((__used__)) const char * GIT_VERSION_##v = NULL #define GIT_VERSION_EXPEND(v) GIT_VERSION_CATTER(v) /* VERSION TAG */ #ifdef GIT_VERSION GIT_VERSION_EXPEND(GIT_VERSION); #else static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL; #endif #undef GIT_VERSION_CATTER #undef GIT_VERSION_EXPEND #ifdef __cplusplus } #endif const char QUIC_VERSION_20200603=0; static int parse_quic_port(char *port_list, unsigned short *quic_port, int quic_port_num) { int i=0,ret=0; int port_num=0; int range_len=0,used_len=0; char buf[256]={0}; unsigned short s_port=0,e_port=0; char *begin=NULL,*end=NULL,*pchr=NULL; if(port_list==NULL) { return 0; } begin=port_list; end=NULL; range_len=strlen(port_list); while(range_len>used_len) { end=index(begin, ';'); if(end==NULL) { end=begin+range_len-used_len; } if(end==begin) { break; } memset(buf, 0, sizeof(buf)); strncpy(buf, begin, end-begin); used_len+=end-begin+1; if(range_len>used_len) { begin=end+1; } pchr=strchr(buf, '-'); if(pchr == NULL) { s_port=(unsigned short)atoi(buf); e_port=s_port; } else { ret=sscanf(buf, "%hu-%hu", &s_port, &e_port); if(ret!=2) { continue; } } for(i=s_port; i<=e_port && port_numsni) { dictator_free(thread_seq, client_hello->sni); client_hello->sni=NULL; } if(client_hello->user_agent) { dictator_free(thread_seq, client_hello->user_agent); client_hello->user_agent=NULL; } dictator_free(thread_seq, client_hello); client_hello=NULL; return ; } void quic_free_context(const struct streaminfo *a_stream, int bridge_id, void *data) { if(NULL!=data) { struct quic_context *context = (struct quic_context *)data; quic_free_client_hello(context->quic_info.client_hello, a_stream->threadnum); dictator_free(a_stream->threadnum, data); } } extern "C" unsigned char QUIC_ENTRY(const struct streaminfo *pstream, void**pme, int thread_seq, const void *a_packet) { if((g_quic_param.quic_interested_region_flagopstate==OP_STATE_PENDING) { *pme=stream_bridge_async_data_get(pstream, g_quic_param.context_bridge_id); if(*pme==NULL) { *pme=dictator_malloc(thread_seq, sizeof(struct quic_context)); memset(*pme, 0, sizeof(struct quic_context)); } } unsigned char state=0; struct quic_context *context=(struct quic_context *)*pme; state=quic_analyze_entry(pstream, context, thread_seq, a_packet); if(state&APP_STATE_DROPME || pstream->opstate==OP_STATE_CLOSE) { quic_call_business_plug(pstream, context, NULL, 0, QUIC_INTEREST_KEY_MASK, a_packet); quic_free_context(pstream, g_quic_param.context_bridge_id, *pme); stream_bridge_async_data_put(pstream, g_quic_param.context_bridge_id, NULL); *pme=NULL; return state; } return APP_STATE_GIVEME; } extern "C" int QUIC_INIT(void) { int ret=0; FILE *fp=NULL; char buff[2048]={0}; int region_id=0; char region_name[REGION_NAME_LEN]={0}; memset(&g_quic_param,0,sizeof(struct quic_param)); MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "LOG_LEVEL", &g_quic_param.level, RLOG_LV_FATAL); MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "LOG_PATH", g_quic_param.log_path, sizeof(g_quic_param.log_path), "./log/quic/quic"); MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "DECRYPTED_SWITCH", &g_quic_param.decrypted_switch, 2); MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "MAX_PARSE_PKT_NUM", &g_quic_param.max_parse_pkt_num, 3); MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "QUIC_PORT_LIST", buff, sizeof(buff), "443;8443;"); g_quic_param.quic_port_num=parse_quic_port(buff, g_quic_param.quic_port_list, SUPPORT_QUIC_PORT_NUM); g_quic_param.logger=MESA_create_runtime_log_handle(g_quic_param.log_path, g_quic_param.level); if(g_quic_param.logger==NULL) { printf("MESA_create_runtime_log_handle failed, level: %d log_path: %s", g_quic_param.level, g_quic_param.log_path); return -1; } if(((fp = fopen(g_quic_regionname_conffile, "r"))!=NULL)) { while(fgets(buff, sizeof(buff), fp)) { ret = sscanf(buff, "%d\t%s", ®ion_id, region_name); if(2>ret) { fclose(fp); MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_READCONF", "Read error, Please check %s, region_line: %s", g_quic_regionname_conffile, buff); return -1; } if(region_id>MAX_REGION_NUM) { fclose(fp); MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_READCONF", "Read error, Please check %s, bigger than MAX_REGION_NUM, region_line: %s", g_quic_regionname_conffile, buff); return -1; } memcpy(g_quic_param.quic_conf_regionname[region_id], region_name, MIN(sizeof(g_quic_param.quic_conf_regionname[region_id])-1, strlen(region_name))); g_quic_param.quic_region_cnt++; memset(region_name, 0, sizeof(region_name)); } fclose(fp); } else { MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_READCONF", "Open %s error, Please check %s", g_quic_regionname_conffile, g_quic_regionname_conffile); return -1; } g_quic_param.context_bridge_id=stream_bridge_build("QUIC_CONTEXT", "w"); stream_bridge_register_data_free_cb(g_quic_param.context_bridge_id, quic_free_context); return 0; } extern "C" void QUIC_GETPLUGID(unsigned short plugid) { g_quic_param.quic_plugid = plugid; MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_GETPLUGID", "quic_plugid: %d", plugid); } extern "C" void QUIC_PROT_FUNSTAT(unsigned long long protflag) { if(0==protflag){ return; } g_quic_param.quic_interested_region_flag=protflag; MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_PROT_FUNSTAT", "interested_region_flag: %llu", g_quic_param.quic_interested_region_flag); return; } extern "C" unsigned long long quic_getRegionID(char *string, int str_len,const char g_string[MAX_REGION_NUM][REGION_NAME_LEN]) { unsigned long long i=0; for(i=0;i