2020-05-12 12:18:02 +08:00
|
|
|
/*
|
2021-11-10 11:55:22 +03:00
|
|
|
* quic_entry.cpp
|
2020-05-12 12:18:02 +08:00
|
|
|
*
|
2021-11-10 11:55:22 +03:00
|
|
|
* Created on: 2021-11-09
|
|
|
|
|
* Author: liuxueli
|
2020-05-12 12:18:02 +08:00
|
|
|
*/
|
2021-11-10 11:55:22 +03:00
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
#include <stdio.h>
|
2023-06-27 13:34:19 +08:00
|
|
|
|
|
|
|
|
#include <MESA/stream.h>
|
2020-05-22 18:44:00 +08:00
|
|
|
#include <MESA/MESA_prof_load.h>
|
2023-06-27 13:34:19 +08:00
|
|
|
#include <MESA/MESA_handle_logger.h>
|
|
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
#include "quic.h"
|
|
|
|
|
#include "quic_entry.h"
|
|
|
|
|
#include "quic_process.h"
|
|
|
|
|
#include "quic_deprotection.h"
|
2020-05-12 12:18:02 +08:00
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
struct quic_param g_quic_param;
|
2020-05-22 18:44:00 +08:00
|
|
|
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
|
|
|
|
|
|
2020-06-03 15:43:00 +08:00
|
|
|
const char QUIC_VERSION_20200603=0;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2021-09-18 17:15:54 +08:00
|
|
|
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_num<quic_port_num; i++)
|
|
|
|
|
{
|
|
|
|
|
quic_port[port_num++]=i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return port_num;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
int quic_init_context(void **pme, int thread_seq)
|
2020-05-22 18:44:00 +08:00
|
|
|
{
|
2021-11-10 11:55:22 +03:00
|
|
|
struct quic_context *context=(struct quic_context *)dictator_malloc(thread_seq, sizeof(struct quic_context));
|
|
|
|
|
memset(context, 0, sizeof(struct quic_context));
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
*pme=(void*)context;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
void quic_free_client_hello(struct quic_client_hello *client_hello, int thread_seq)
|
2020-05-22 18:44:00 +08:00
|
|
|
{
|
2021-11-10 11:55:22 +03:00
|
|
|
if(client_hello==NULL)
|
|
|
|
|
{
|
|
|
|
|
return ;
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
if(client_hello->sni)
|
2020-05-22 18:44:00 +08:00
|
|
|
{
|
2021-11-10 11:55:22 +03:00
|
|
|
dictator_free(thread_seq, client_hello->sni);
|
|
|
|
|
client_hello->sni=NULL;
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
if(client_hello->user_agent)
|
|
|
|
|
{
|
|
|
|
|
dictator_free(thread_seq, client_hello->user_agent);
|
|
|
|
|
client_hello->user_agent=NULL;
|
2020-05-22 18:44:00 +08:00
|
|
|
}
|
2021-11-10 11:55:22 +03:00
|
|
|
|
|
|
|
|
dictator_free(thread_seq, client_hello);
|
|
|
|
|
client_hello=NULL;
|
|
|
|
|
|
|
|
|
|
return ;
|
|
|
|
|
}
|
2020-05-29 15:10:01 +08:00
|
|
|
|
2023-06-27 13:34:19 +08:00
|
|
|
void quic_free_context(const struct streaminfo *a_stream, int bridge_id, void *data)
|
2021-11-10 11:55:22 +03:00
|
|
|
{
|
2023-06-27 13:34:19 +08:00
|
|
|
if(NULL!=data)
|
2021-11-10 11:55:22 +03:00
|
|
|
{
|
2023-06-27 13:34:19 +08:00
|
|
|
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);
|
2021-11-10 11:55:22 +03:00
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
}
|
|
|
|
|
|
2023-06-27 13:34:19 +08:00
|
|
|
extern "C" unsigned char QUIC_ENTRY(const struct streaminfo *pstream, void**pme, int thread_seq, const void *a_packet)
|
2020-05-22 18:44:00 +08:00
|
|
|
{
|
2021-11-10 11:55:22 +03:00
|
|
|
if((g_quic_param.quic_interested_region_flag<QUIC_KEY) || (!is_quic_port(pstream)))
|
|
|
|
|
{
|
|
|
|
|
return APP_STATE_DROPME;
|
|
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
2023-06-27 13:34:19 +08:00
|
|
|
if(pstream->opstate==OP_STATE_PENDING)
|
2021-11-10 11:55:22 +03:00
|
|
|
{
|
2023-06-27 13:34:19 +08:00
|
|
|
*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));
|
|
|
|
|
}
|
2021-11-10 11:55:22 +03:00
|
|
|
}
|
2023-06-27 13:34:19 +08:00
|
|
|
|
|
|
|
|
unsigned char state=0;
|
|
|
|
|
struct quic_context *context=(struct quic_context *)*pme;
|
2021-11-10 19:39:17 +03:00
|
|
|
|
2023-02-16 10:20:46 +08:00
|
|
|
state=quic_analyze_entry(pstream, context, thread_seq, a_packet);
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2023-02-16 10:20:46 +08:00
|
|
|
if(state&APP_STATE_DROPME || pstream->opstate==OP_STATE_CLOSE)
|
|
|
|
|
{
|
|
|
|
|
quic_call_business_plug(pstream, context, NULL, 0, QUIC_INTEREST_KEY_MASK, a_packet);
|
2023-06-27 13:34:19 +08:00
|
|
|
quic_free_context(pstream, g_quic_param.context_bridge_id, *pme);
|
|
|
|
|
stream_bridge_async_data_put(pstream, g_quic_param.context_bridge_id, NULL);
|
2021-11-10 11:55:22 +03:00
|
|
|
*pme=NULL;
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return APP_STATE_GIVEME;
|
2020-05-22 18:44:00 +08:00
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
extern "C" int QUIC_INIT(void)
|
2020-05-12 12:18:02 +08:00
|
|
|
{
|
2021-09-10 13:19:28 +08:00
|
|
|
int ret=0;
|
2020-05-22 18:44:00 +08:00
|
|
|
FILE *fp=NULL;
|
2021-09-18 17:15:54 +08:00
|
|
|
char buff[2048]={0};
|
2020-05-22 18:44:00 +08:00
|
|
|
int region_id=0;
|
|
|
|
|
char region_name[REGION_NAME_LEN]={0};
|
|
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
memset(&g_quic_param,0,sizeof(struct quic_param));
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2021-09-10 13:19:28 +08:00
|
|
|
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");
|
2020-05-22 18:44:00 +08:00
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "DECRYPTED_SWITCH", &g_quic_param.decrypted_switch, 2);
|
2021-11-10 19:39:17 +03:00
|
|
|
MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "MAX_PARSE_PKT_NUM", &g_quic_param.max_parse_pkt_num, 3);
|
2021-09-10 13:19:28 +08:00
|
|
|
|
2021-09-18 17:15:54 +08:00
|
|
|
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);
|
|
|
|
|
|
2021-09-10 13:19:28 +08:00
|
|
|
g_quic_param.logger=MESA_create_runtime_log_handle(g_quic_param.log_path, g_quic_param.level);
|
2020-05-22 18:44:00 +08:00
|
|
|
if(g_quic_param.logger==NULL)
|
|
|
|
|
{
|
2021-09-10 13:19:28 +08:00
|
|
|
printf("MESA_create_runtime_log_handle failed, level: %d log_path: %s", g_quic_param.level, g_quic_param.log_path);
|
2020-05-12 12:18:02 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
if(((fp = fopen(g_quic_regionname_conffile, "r"))!=NULL))
|
|
|
|
|
{
|
2021-09-18 17:15:54 +08:00
|
|
|
while(fgets(buff, sizeof(buff), fp))
|
2020-05-22 18:44:00 +08:00
|
|
|
{
|
2021-09-18 17:15:54 +08:00
|
|
|
ret = sscanf(buff, "%d\t%s", ®ion_id, region_name);
|
2020-05-22 18:44:00 +08:00
|
|
|
if(2>ret)
|
|
|
|
|
{
|
|
|
|
|
fclose(fp);
|
2021-09-18 17:15:54 +08:00
|
|
|
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);
|
2020-05-22 18:44:00 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if(region_id>MAX_REGION_NUM)
|
|
|
|
|
{
|
|
|
|
|
fclose(fp);
|
2021-09-18 17:15:54 +08:00
|
|
|
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);
|
2020-05-22 18:44:00 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-27 13:34:19 +08:00
|
|
|
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)));
|
2020-05-22 18:44:00 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-27 13:34:19 +08:00
|
|
|
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);
|
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
return 0;
|
2021-11-10 11:55:22 +03:00
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
extern "C" void QUIC_GETPLUGID(unsigned short plugid)
|
2020-05-12 12:18:02 +08:00
|
|
|
{
|
|
|
|
|
g_quic_param.quic_plugid = plugid;
|
2020-05-22 18:44:00 +08:00
|
|
|
MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_GETPLUGID", "quic_plugid: %d", plugid);
|
2020-05-12 12:18:02 +08:00
|
|
|
}
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
extern "C" void QUIC_PROT_FUNSTAT(unsigned long long protflag)
|
2020-05-12 12:18:02 +08:00
|
|
|
{
|
|
|
|
|
if(0==protflag){
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
return;
|
2021-11-10 11:55:22 +03:00
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
extern "C" unsigned long long quic_getRegionID(char *string, int str_len,const char g_string[MAX_REGION_NUM][REGION_NAME_LEN])
|
2020-05-12 12:18:02 +08:00
|
|
|
{
|
|
|
|
|
unsigned long long i=0;
|
|
|
|
|
for(i=0;i<g_quic_param.quic_region_cnt;i++)
|
|
|
|
|
{
|
|
|
|
|
if(0==strcasecmp(g_string[i], string))
|
|
|
|
|
{
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
extern "C" long long QUIC_FLAG_CHANGE(char* flag_str)
|
2020-05-12 12:18:02 +08:00
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2020-05-22 18:44:00 +08:00
|
|
|
MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_FLAG_CHANGE", "Read %s error, flag_str: %d", region_name, flag_str);
|
2020-05-12 12:18:02 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
protflag |= ((long long)1)<<region_id;
|
|
|
|
|
memset(region_name, 0, REGION_NAME_LEN);
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_FATAL, "QUIC_FLAG_CHANGE", "protflag: %llu", protflag);
|
2020-05-12 12:18:02 +08:00
|
|
|
return protflag;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-10 11:55:22 +03:00
|
|
|
extern "C" void QUIC_DESTROY(void)
|
2020-05-12 12:18:02 +08:00
|
|
|
{
|
2021-11-10 11:55:22 +03:00
|
|
|
return ;
|
2020-06-03 15:43:00 +08:00
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|