feat: adapt to stellar-2.0

This commit is contained in:
lijia
2024-06-07 19:03:56 +08:00
parent 1ab2559887
commit 82cd2ced07
17 changed files with 605 additions and 723 deletions

View File

@@ -6,8 +6,7 @@
*/
#include <stdio.h>
#include <MESA/stream.h>
#include <assert.h>
#include <MESA/MESA_prof_load.h>
#include <MESA/MESA_handle_logger.h>
@@ -15,15 +14,19 @@
#include "quic_entry.h"
#include "quic_process.h"
#include "quic_deprotection.h"
#include "quic_util.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";
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 <stellar/stellar.h>
#include <stellar/session.h>
#include <stellar/session_mq.h>
#include <stellar/session_exdata.h>
#define GIT_VERSION_CATTER(v) __attribute__((__used__)) const char * GIT_VERSION_##v = NULL
#define GIT_VERSION_EXPEND(v) GIT_VERSION_CATTER(v)
@@ -100,233 +103,140 @@ static int parse_quic_port(char *port_list, unsigned short *quic_port, int quic_
for(i=s_port; i<=e_port && port_num<quic_port_num; i++)
{
quic_port[port_num++]=i;
quic_port[port_num++]= htons((unsigned short)i);
}
}
return port_num;
}
int quic_init_context(void **pme, int thread_seq)
static void free_quicinfo(struct quic_info *quic_info)
{
struct quic_context *context=(struct quic_context *)dictator_malloc(thread_seq, sizeof(struct quic_context));
memset(context, 0, sizeof(struct quic_context));
if(quic_info->sni.str)
FREE(quic_info->sni.str);
*pme=(void*)context;
return 0;
}
void quic_free_client_hello(struct quic_client_hello *client_hello, int thread_seq)
{
if(client_hello==NULL)
{
return ;
}
if(client_hello->sni)
{
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;
if(quic_info->user_agent.str)
FREE(quic_info->user_agent.str);
return ;
}
void quic_free_context(const struct streaminfo *a_stream, int bridge_id, void *data)
extern "C" void quic_on_session_msg_cb(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
{
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);
}
}
struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env;
struct quic_context *context = (struct quic_context *)per_session_ctx;
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_flag<QUIC_KEY) || (!is_quic_port(pstream)))
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)
{
return APP_STATE_DROPME;
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;
}
if(pstream->opstate==OP_STATE_PENDING)
payload = session_get0_current_payload(sess, &payload_len);
if(NULL == payload || payload_len <= 0)
{
*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)
{
if(context->link_state==1)
{
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", &region_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);
quic_analyze_entry(sess, quic_plugin_env, context, thread_seq, payload, payload_len);
return;
}
extern "C" unsigned long long quic_getRegionID(char *string, int str_len,const char g_string[MAX_REGION_NUM][REGION_NAME_LEN])
void *quic_session_ctx_new_cb(struct session *sess, void *plugin_env)
{
unsigned long long i=0;
for(i=0;i<g_quic_param.quic_region_cnt;i++)
struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env;
if(0 == quic_protocol_identify(sess, quic_plugin_env))
{
if(0==strcasecmp(g_string[i], string))
{
return i;
}
stellar_session_plugin_dettach_current_session(sess);
return NULL;
}
return 0;
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;
}
extern "C" long long QUIC_FLAG_CHANGE(char* flag_str)
void quic_session_ctx_free_cb(struct session *sess, void *session_ctx, void *plugin_env)
{
if(flag_str==NULL) return -1;
long long protflag = 0;
long long region_id = 0;
char *start_token = flag_str;
char *end_token = flag_str;
char *end_pos = flag_str+strlen(flag_str);
char region_name[REGION_NAME_LEN] = {0};
while (end_token < end_pos)
{
end_token = (char*)memchr(start_token, ',', end_pos-start_token);
if(end_token!=NULL)
{
memcpy(region_name, start_token, end_token-start_token);
start_token = end_token+1;
end_token += 1;
}
else
{
memcpy(region_name, start_token, end_pos-start_token);
end_token = end_pos;
}
region_id = quic_getRegionID(region_name, strlen(region_name), g_quic_param.quic_conf_regionname);
if(-1==region_id)
{
MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_FLAG_CHANGE", "Read %s error, flag_str: %d", region_name, flag_str);
return -1;
}
protflag |= ((long long)1)<<region_id;
memset(region_name, 0, REGION_NAME_LEN);
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_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_FLAG_CHANGE", "protflag: %llu", protflag);
return protflag;
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_DESTROY(void)
extern "C" void QUIC_UNLOAD(void *plugin_env)
{
MESA_destroy_runtime_log_handle(g_quic_param.logger);
g_quic_param.logger = NULL;
return ;
}
struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env;
MESA_destroy_runtime_log_handle(quic_plugin_env->logger);
FREE(plugin_env);
return;
}