/* * 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" #include "quic_util.h" static const char *g_quic_proto_conffile="./conf/quic/main.conf"; // static const char *g_quic_regionname_conffile="./conf/quic/quic.conf"; static const char *g_quic_log_path = "./log/quic/quic"; #ifdef __cplusplus extern "C" { #endif #include #include #include #include #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.str) FREE(quic_info->sni.str); if(quic_info->user_agent.str) FREE(quic_info->user_agent.str); return ; } extern "C" void quic_on_session_msg_cb(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env) { struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env; struct quic_context *context = (struct quic_context *)per_session_ctx; int thread_seq = session_get_current_thread_id(sess); const char *payload = NULL; size_t payload_len = -1; enum session_state sstate = session_get_current_state(sess); if(sstate == SESSION_STATE_CLOSING) { struct quic_message *qmsg = quic_create_message(QUIC_FREE, context); quic_session_mq_publish_message_safe(sess, quic_plugin_env->quic_topic_id, qmsg); context->msg_state[QUIC_FREE] = 1; } payload = session_get0_current_payload(sess, &payload_len); if(NULL == payload || payload_len <= 0) { return; } quic_analyze_entry(sess, quic_plugin_env, context, thread_seq, payload, payload_len); return; } void *quic_session_ctx_new_cb(struct session *sess, void *plugin_env) { struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env; if(0 == quic_protocol_identify(sess, quic_plugin_env)) { stellar_session_plugin_dettach_current_session(sess); return NULL; } int thread_seq = session_get_current_thread_id(sess); size_t payload_len = -1; const char * payload = session_get0_current_payload(sess, &payload_len); if(NULL == payload || payload_len <= 0) { stellar_session_plugin_dettach_current_session(sess); return NULL; } struct quic_info tmp_qinfo = {}; if(PARSE_RESULT_UNKNOWN == parse_quic_all_version(quic_plugin_env, &tmp_qinfo, payload, payload_len, thread_seq)) { stellar_session_plugin_dettach_current_session(sess); return NULL; } struct quic_context *qcontext = (struct quic_context *)CALLOC(1, sizeof(struct quic_context)); memcpy(&qcontext->quic_info, &tmp_qinfo, sizeof(struct quic_info)); struct quic_message *qmsg = quic_create_message(QUIC_NEW, qcontext); quic_session_mq_publish_message_safe(sess, quic_plugin_env->quic_topic_id, qmsg); return (void *)qcontext; } void quic_session_ctx_free_cb(struct session *sess, void *session_ctx, void *plugin_env) { if(session_ctx){ struct quic_context *qcontext = (struct quic_context *)session_ctx; free_quicinfo(&qcontext->quic_info); FREE(session_ctx); } return; } void quic_session_exdata_free_cb(struct session *sess, int idx, void *ex_ptr, void *arg) { return; } void quic_msg_free_cb(struct session *sess, void *msg, void *msg_free_arg) { FREE(msg); } extern "C" void *QUIC_ONLOAD(struct stellar *st) { char buff[2048]={0}; struct quic_param *quic_plugin_env = (struct quic_param *)CALLOC(1, sizeof(struct quic_param)); quic_plugin_env->st = st; MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "LOG_LEVEL", &quic_plugin_env->level, RLOG_LV_FATAL); MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "LOG_PATH", quic_plugin_env->log_path, sizeof(quic_plugin_env->log_path), g_quic_log_path); MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "DECRYPTED_SWITCH", &quic_plugin_env->decrypted_switch, 2); MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "MAX_PARSE_PKT_NUM", &quic_plugin_env->max_parse_pkt_num, 3); MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "QUIC_PORT_LIST", buff, sizeof(buff), "443;8443;"); quic_plugin_env->quic_port_num=parse_quic_port(buff, quic_plugin_env->quic_port_list, SUPPORT_QUIC_PORT_NUM); quic_plugin_env->logger=MESA_create_runtime_log_handle(quic_plugin_env->log_path, quic_plugin_env->level); if(quic_plugin_env->logger==NULL) { fprintf(stderr, "MESA_create_runtime_log_handle failed, level: %d log_path: %s", quic_plugin_env->level, quic_plugin_env->log_path); return NULL; } quic_plugin_env->quic_plugid = stellar_session_plugin_register(st, quic_session_ctx_new_cb, quic_session_ctx_free_cb, quic_plugin_env); assert(quic_plugin_env->quic_plugid >= 0); quic_plugin_env->exdata_id=stellar_session_exdata_new_index(st, "QUIC_EXDATA", quic_session_exdata_free_cb, quic_plugin_env); assert(quic_plugin_env->exdata_id >= 0); quic_plugin_env->udp_topic_id=stellar_session_mq_get_topic_id(st, TOPIC_UDP); assert(quic_plugin_env->udp_topic_id >= 0); stellar_session_mq_subscribe(st, quic_plugin_env->udp_topic_id, quic_on_session_msg_cb, quic_plugin_env->quic_plugid); quic_plugin_env->quic_topic_id=stellar_session_mq_create_topic(st, QUIC_DECODER_TOPIC, quic_msg_free_cb, quic_plugin_env); assert(quic_plugin_env->quic_topic_id >= 0); return (void *)quic_plugin_env; } extern "C" void QUIC_UNLOAD(void *plugin_env) { struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env; MESA_destroy_runtime_log_handle(quic_plugin_env->logger); FREE(plugin_env); return; }