diff --git a/include/quic.h b/include/quic.h index 33181cd..dcb25c8 100644 --- a/include/quic.h +++ b/include/quic.h @@ -49,7 +49,7 @@ struct quic_info //buff_len minimun 32bytes int quic_version_int2string(unsigned int version, char *buff, int buff_len); -//ret: 0: not quic, >0: 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); +//ret: NULL: not quic, quic_info: quic version +struct quic_info *quic_protocol_identify(const struct streaminfo *a_stream); #endif /* SRC__QUIC_H__ */ diff --git a/src/quic_entry.cpp b/src/quic_entry.cpp index dfa5566..7fbed33 100644 --- a/src/quic_entry.cpp +++ b/src/quic_entry.cpp @@ -6,9 +6,11 @@ */ #include -#include -#include + +#include #include +#include + #include "quic.h" #include "quic_entry.h" #include "quic_process.h" @@ -141,44 +143,44 @@ void quic_free_client_hello(struct quic_client_hello *client_hello, int thread_s 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_flagopstate==OP_STATE_PENDING) { - quic_init_context(pme, thread_seq); - context=(struct quic_context *)*pme; + *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(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; return state; } @@ -230,7 +232,7 @@ extern "C" int QUIC_INIT(void) 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++; memset(region_name, 0, sizeof(region_name)); } @@ -243,6 +245,9 @@ extern "C" int QUIC_INIT(void) 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; } diff --git a/src/quic_entry.h b/src/quic_entry.h index 90e080c..27a33e7 100644 --- a/src/quic_entry.h +++ b/src/quic_entry.h @@ -3,6 +3,10 @@ #include "quic.h" +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + #define FALSE 0x00 #define TRUE 0x01 #define MAYBE 0x02 @@ -29,6 +33,7 @@ struct quic_param int quic_port_num; int decrypted_switch; int max_parse_pkt_num; + int context_bridge_id; unsigned short quic_port_list[SUPPORT_QUIC_PORT_NUM]; char quic_conf_regionname[MAX_REGION_NUM][REGION_NAME_LEN]; char log_path[128]; @@ -47,8 +52,7 @@ enum quic_mes_type{ }; extern struct quic_param g_quic_param; -int is_quic_port(struct streaminfo *pstream); -void quic_free_client_hello(struct quic_client_hello *client_hello, int thread_seq); +int is_quic_port(const struct streaminfo *pstream); #endif /* SRC_QUIC_ANALYSIS_H_ */ diff --git a/src/quic_process.cpp b/src/quic_process.cpp index 833c931..711cf15 100644 --- a/src/quic_process.cpp +++ b/src/quic_process.cpp @@ -31,10 +31,6 @@ enum PARSE_RESULT #define PRINTADDR(a, b) ((b)addr), a->threadnum) : "") #endif -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - struct quic_client_hello_msg_hdr { uint8_t handshake_type; @@ -57,7 +53,7 @@ int check_port(unsigned short port) return 0; } -int is_quic_port(struct streaminfo *pstream) +int is_quic_port(const struct streaminfo *pstream) { unsigned short source=0, dest=0; @@ -152,7 +148,7 @@ int quic_call_business_state(struct quic_context *context) 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 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.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) { @@ -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; char state=APP_STATE_GIVEME; - if(pstream==NULL || pstream->pudpdetail==NULL) + if(pstream==NULL || pstream->pudpdetail==NULL || context==NULL) { return APP_STATE_DROPME; } @@ -826,7 +822,7 @@ unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context switch(context->pre_parse_state) { - case PARSE_RESULT_CLIENT_HELLO: + case PARSE_RESULT_CLIENT_HELLO: parse_result=PARSE_RESULT_PAYLOAD; break; 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_UNKNOWN: 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) { parse_result=PARSE_RESULT_PAYLOAD; @@ -869,49 +879,30 @@ unsigned char quic_analyze_entry(struct streaminfo *pstream, struct quic_context 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) { - 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(quic_info.client_hello!=NULL) - { - *out_sni_len=copy_client_hello_extension(quic_info.client_hello->sni, out_sni, *out_sni_len); - *out_ua_len=copy_client_hello_extension(quic_info.client_hello->user_agent, out_ua, *out_ua_len); - quic_free_client_hello(quic_info.client_hello, a_stream->threadnum); - } - else - { - *out_sni_len=0; - *out_ua_len=0; - } - - quic_version=quic_info.quic_version; + struct quic_context *context=(struct quic_context *)dictator_malloc(a_stream->threadnum, sizeof(struct quic_context)); + memset(context, 0, sizeof(struct quic_context)); + context->quic_info=tmp_quic_info; + context->parse_first_pkt=1; + context->pre_parse_state=PARSE_RESULT_UNKNOWN; + + stream_bridge_async_data_put(a_stream, g_quic_param.context_bridge_id, (void *)context); + + return &(context->quic_info); } - return quic_version; + return NULL; } diff --git a/src/quic_process.h b/src/quic_process.h index b3cf8a1..c0583c6 100644 --- a/src/quic_process.h +++ b/src/quic_process.h @@ -284,13 +284,14 @@ struct quic_context unsigned char link_state; unsigned char parse_pkt_cnt; unsigned char pre_parse_state; - unsigned char padding[5]; + unsigned char parse_first_pkt; + unsigned char padding[4]; void *business_pme; 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_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_analyze_entry(const struct streaminfo *pstream, struct quic_context* context, int thread_seq, const 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