第一个数据包仅解析一次,节省cpu
This commit is contained in:
@@ -49,7 +49,7 @@ struct quic_info
|
|||||||
|
|
||||||
//buff_len minimun 32bytes
|
//buff_len minimun 32bytes
|
||||||
int quic_version_int2string(unsigned int version, char *buff, int buff_len);
|
int quic_version_int2string(unsigned int version, char *buff, int buff_len);
|
||||||
//ret: 0: not quic, >0: quic version
|
//ret: NULL: not quic, quic_info: quic version
|
||||||
unsigned int quic_protocol_identify(struct streaminfo *a_stream, void *a_packet, char *out_sni, int *out_sni_len, char *out_ua, int *out_ua_len);
|
struct quic_info *quic_protocol_identify(const struct streaminfo *a_stream);
|
||||||
|
|
||||||
#endif /* SRC__QUIC_H__ */
|
#endif /* SRC__QUIC_H__ */
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <MESA/stream_inc/stream_base.h>
|
|
||||||
#include <MESA/MESA_handle_logger.h>
|
#include <MESA/stream.h>
|
||||||
#include <MESA/MESA_prof_load.h>
|
#include <MESA/MESA_prof_load.h>
|
||||||
|
#include <MESA/MESA_handle_logger.h>
|
||||||
|
|
||||||
#include "quic.h"
|
#include "quic.h"
|
||||||
#include "quic_entry.h"
|
#include "quic_entry.h"
|
||||||
#include "quic_process.h"
|
#include "quic_process.h"
|
||||||
@@ -141,44 +143,44 @@ void quic_free_client_hello(struct quic_client_hello *client_hello, int thread_s
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void quic_free_context(void** pme, int thread_seq)
|
void quic_free_context(const struct streaminfo *a_stream, int bridge_id, void *data)
|
||||||
{
|
{
|
||||||
if(NULL==*pme)
|
if(NULL!=data)
|
||||||
{
|
{
|
||||||
return ;
|
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_context *context = (struct quic_context *)*pme;
|
|
||||||
quic_free_client_hello(context->quic_info.client_hello, thread_seq);
|
|
||||||
|
|
||||||
dictator_free(thread_seq, *pme);
|
|
||||||
*pme=NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" unsigned char QUIC_ENTRY(struct streaminfo *pstream, void**pme, int thread_seq, void *a_packet)
|
extern "C" unsigned char QUIC_ENTRY(const struct streaminfo *pstream, void**pme, int thread_seq, const void *a_packet)
|
||||||
{
|
{
|
||||||
unsigned char state=0;
|
|
||||||
struct quic_context *context=(struct quic_context *)*pme;
|
|
||||||
|
|
||||||
if((g_quic_param.quic_interested_region_flag<QUIC_KEY) || (!is_quic_port(pstream)))
|
if((g_quic_param.quic_interested_region_flag<QUIC_KEY) || (!is_quic_port(pstream)))
|
||||||
{
|
{
|
||||||
return APP_STATE_DROPME;
|
return APP_STATE_DROPME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*pme==NULL)
|
if(pstream->opstate==OP_STATE_PENDING)
|
||||||
{
|
{
|
||||||
quic_init_context(pme, thread_seq);
|
*pme=stream_bridge_async_data_get(pstream, g_quic_param.context_bridge_id);
|
||||||
context=(struct quic_context *)*pme;
|
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);
|
state=quic_analyze_entry(pstream, context, thread_seq, a_packet);
|
||||||
|
|
||||||
if(state&APP_STATE_DROPME || pstream->opstate==OP_STATE_CLOSE)
|
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_call_business_plug(pstream, context, NULL, 0, QUIC_INTEREST_KEY_MASK, a_packet);
|
||||||
quic_free_context(pme, thread_seq);
|
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;
|
*pme=NULL;
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -230,7 +232,7 @@ extern "C" int QUIC_INIT(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(g_quic_param.quic_conf_regionname[region_id], region_name, strlen(region_name));
|
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++;
|
g_quic_param.quic_region_cnt++;
|
||||||
memset(region_name, 0, sizeof(region_name));
|
memset(region_name, 0, sizeof(region_name));
|
||||||
}
|
}
|
||||||
@@ -243,6 +245,9 @@ extern "C" int QUIC_INIT(void)
|
|||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include "quic.h"
|
#include "quic.h"
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FALSE 0x00
|
#define FALSE 0x00
|
||||||
#define TRUE 0x01
|
#define TRUE 0x01
|
||||||
#define MAYBE 0x02
|
#define MAYBE 0x02
|
||||||
@@ -29,6 +33,7 @@ struct quic_param
|
|||||||
int quic_port_num;
|
int quic_port_num;
|
||||||
int decrypted_switch;
|
int decrypted_switch;
|
||||||
int max_parse_pkt_num;
|
int max_parse_pkt_num;
|
||||||
|
int context_bridge_id;
|
||||||
unsigned short quic_port_list[SUPPORT_QUIC_PORT_NUM];
|
unsigned short quic_port_list[SUPPORT_QUIC_PORT_NUM];
|
||||||
char quic_conf_regionname[MAX_REGION_NUM][REGION_NAME_LEN];
|
char quic_conf_regionname[MAX_REGION_NUM][REGION_NAME_LEN];
|
||||||
char log_path[128];
|
char log_path[128];
|
||||||
@@ -47,8 +52,7 @@ enum quic_mes_type{
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern struct quic_param g_quic_param;
|
extern struct quic_param g_quic_param;
|
||||||
int is_quic_port(struct streaminfo *pstream);
|
int is_quic_port(const struct streaminfo *pstream);
|
||||||
void quic_free_client_hello(struct quic_client_hello *client_hello, int thread_seq);
|
|
||||||
|
|
||||||
#endif /* SRC_QUIC_ANALYSIS_H_ */
|
#endif /* SRC_QUIC_ANALYSIS_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ enum PARSE_RESULT
|
|||||||
#define PRINTADDR(a, b) ((b)<RLOG_LV_FATAL ? printaddr(&(a->addr), a->threadnum) : "")
|
#define PRINTADDR(a, b) ((b)<RLOG_LV_FATAL ? printaddr(&(a->addr), a->threadnum) : "")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct quic_client_hello_msg_hdr
|
struct quic_client_hello_msg_hdr
|
||||||
{
|
{
|
||||||
uint8_t handshake_type;
|
uint8_t handshake_type;
|
||||||
@@ -57,7 +53,7 @@ int check_port(unsigned short port)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_quic_port(struct streaminfo *pstream)
|
int is_quic_port(const struct streaminfo *pstream)
|
||||||
{
|
{
|
||||||
unsigned short source=0, dest=0;
|
unsigned short source=0, dest=0;
|
||||||
|
|
||||||
@@ -152,7 +148,7 @@ int quic_call_business_state(struct quic_context *context)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char quic_call_business_plug(struct streaminfo *pstream, struct quic_context *context, void *buff, int buff_len, enum quic_interested_region region_mask, void *a_packet)
|
unsigned char quic_call_business_plug(const struct streaminfo *pstream, struct quic_context *context, void *buff, int buff_len, enum quic_interested_region region_mask, const void *a_packet)
|
||||||
{
|
{
|
||||||
char state=PROT_STATE_GIVEME;
|
char state=PROT_STATE_GIVEME;
|
||||||
char app_state=APP_STATE_GIVEME;
|
char app_state=APP_STATE_GIVEME;
|
||||||
@@ -176,7 +172,7 @@ unsigned char quic_call_business_plug(struct streaminfo *pstream, struct quic_co
|
|||||||
session_info.buf=buff;
|
session_info.buf=buff;
|
||||||
session_info.buflen=buff_len;
|
session_info.buflen=buff_len;
|
||||||
}
|
}
|
||||||
state=PROT_PROCESS(&session_info, &(context->business_pme), pstream->threadnum, pstream, a_packet);
|
state=PROT_PROCESS(&session_info, &(context->business_pme), pstream->threadnum, (struct streaminfo *)pstream, a_packet);
|
||||||
|
|
||||||
if(state&PROT_STATE_DROPPKT)
|
if(state&PROT_STATE_DROPPKT)
|
||||||
{
|
{
|
||||||
@@ -812,12 +808,12 @@ unsigned char parse_quic_all_version(struct quic_info *quic_info, const char *pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context* context, int thread_seq, void* a_packet)
|
unsigned char quic_analyze_entry(const struct streaminfo *pstream, struct quic_context* context, int thread_seq, const void* a_packet)
|
||||||
{
|
{
|
||||||
unsigned char parse_result=PARSE_RESULT_UNKNOWN;
|
unsigned char parse_result=PARSE_RESULT_UNKNOWN;
|
||||||
char state=APP_STATE_GIVEME;
|
char state=APP_STATE_GIVEME;
|
||||||
|
|
||||||
if(pstream==NULL || pstream->pudpdetail==NULL)
|
if(pstream==NULL || pstream->pudpdetail==NULL || context==NULL)
|
||||||
{
|
{
|
||||||
return APP_STATE_DROPME;
|
return APP_STATE_DROPME;
|
||||||
}
|
}
|
||||||
@@ -826,7 +822,7 @@ unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context
|
|||||||
|
|
||||||
switch(context->pre_parse_state)
|
switch(context->pre_parse_state)
|
||||||
{
|
{
|
||||||
case PARSE_RESULT_CLIENT_HELLO:
|
case PARSE_RESULT_CLIENT_HELLO:
|
||||||
parse_result=PARSE_RESULT_PAYLOAD;
|
parse_result=PARSE_RESULT_PAYLOAD;
|
||||||
break;
|
break;
|
||||||
case PARSE_RESULT_VERSION:
|
case PARSE_RESULT_VERSION:
|
||||||
@@ -839,6 +835,20 @@ unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context
|
|||||||
case PARSE_RESULT_PAYLOAD:
|
case PARSE_RESULT_PAYLOAD:
|
||||||
case PARSE_RESULT_UNKNOWN:
|
case PARSE_RESULT_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
|
if(context->parse_first_pkt==1)
|
||||||
|
{
|
||||||
|
context->parse_first_pkt=0;
|
||||||
|
if(context->quic_info.client_hello==NULL)
|
||||||
|
{
|
||||||
|
parse_result=PARSE_RESULT_VERSION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parse_result=PARSE_RESULT_CLIENT_HELLO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if((context->parse_pkt_cnt++)>=g_quic_param.max_parse_pkt_num)
|
if((context->parse_pkt_cnt++)>=g_quic_param.max_parse_pkt_num)
|
||||||
{
|
{
|
||||||
parse_result=PARSE_RESULT_PAYLOAD;
|
parse_result=PARSE_RESULT_PAYLOAD;
|
||||||
@@ -869,49 +879,30 @@ unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int copy_client_hello_extension(char *src, char *dest, int d_len)
|
struct quic_info *quic_protocol_identify(const struct streaminfo *a_stream)
|
||||||
{
|
{
|
||||||
if(src==NULL || dest==NULL || d_len<=0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int len=MIN((int)strlen(src), d_len-1);
|
|
||||||
memcpy(dest, src, len);
|
|
||||||
dest[len]='\0';
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int quic_protocol_identify(struct streaminfo *a_stream, void *a_packet, char *out_sni, int *out_sni_len, char *out_ua, int *out_ua_len)
|
|
||||||
{
|
|
||||||
unsigned char parse_result=APP_STATE_GIVEME;
|
|
||||||
struct quic_info quic_info={0, NULL};
|
|
||||||
unsigned int quic_version=QUIC_VERSION_UNKNOWN;
|
|
||||||
|
|
||||||
if(!is_quic_port(a_stream) || a_stream==NULL || a_stream->pudpdetail==NULL)
|
if(!is_quic_port(a_stream) || a_stream==NULL || a_stream->pudpdetail==NULL)
|
||||||
{
|
{
|
||||||
return quic_version;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_result=parse_quic_all_version(&quic_info, (const char *)a_stream->pudpdetail->pdata, a_stream->pudpdetail->datalen, a_stream->threadnum);
|
struct quic_info tmp_quic_info={0, NULL};
|
||||||
|
unsigned char parse_result=APP_STATE_GIVEME;
|
||||||
|
|
||||||
|
parse_result=parse_quic_all_version(&tmp_quic_info, (const char *)a_stream->pudpdetail->pdata, a_stream->pudpdetail->datalen, a_stream->threadnum);
|
||||||
if(parse_result!=PARSE_RESULT_UNKNOWN)
|
if(parse_result!=PARSE_RESULT_UNKNOWN)
|
||||||
{
|
{
|
||||||
if(quic_info.client_hello!=NULL)
|
struct quic_context *context=(struct quic_context *)dictator_malloc(a_stream->threadnum, sizeof(struct quic_context));
|
||||||
{
|
memset(context, 0, sizeof(struct quic_context));
|
||||||
*out_sni_len=copy_client_hello_extension(quic_info.client_hello->sni, out_sni, *out_sni_len);
|
context->quic_info=tmp_quic_info;
|
||||||
*out_ua_len=copy_client_hello_extension(quic_info.client_hello->user_agent, out_ua, *out_ua_len);
|
context->parse_first_pkt=1;
|
||||||
quic_free_client_hello(quic_info.client_hello, a_stream->threadnum);
|
context->pre_parse_state=PARSE_RESULT_UNKNOWN;
|
||||||
}
|
|
||||||
else
|
stream_bridge_async_data_put(a_stream, g_quic_param.context_bridge_id, (void *)context);
|
||||||
{
|
|
||||||
*out_sni_len=0;
|
return &(context->quic_info);
|
||||||
*out_ua_len=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
quic_version=quic_info.quic_version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return quic_version;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -284,13 +284,14 @@ struct quic_context
|
|||||||
unsigned char link_state;
|
unsigned char link_state;
|
||||||
unsigned char parse_pkt_cnt;
|
unsigned char parse_pkt_cnt;
|
||||||
unsigned char pre_parse_state;
|
unsigned char pre_parse_state;
|
||||||
unsigned char padding[5];
|
unsigned char parse_first_pkt;
|
||||||
|
unsigned char padding[4];
|
||||||
void *business_pme;
|
void *business_pme;
|
||||||
struct quic_info quic_info;
|
struct quic_info quic_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context* context, int thread_seq, void* a_packet);
|
unsigned char quic_analyze_entry(const struct streaminfo *pstream, struct quic_context* context, int thread_seq, const void* a_packet);
|
||||||
unsigned char quic_call_business_plug(struct streaminfo *pstream, struct quic_context *context, void *buff, int buff_len, enum quic_interested_region region_mask, void *a_packet);
|
unsigned char quic_call_business_plug(const struct streaminfo *pstream, struct quic_context *context, void *buff, int buff_len, enum quic_interested_region region_mask, const void *a_packet);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user