From c0ed0eb78f3e05bc1a30d314169ae296720196c6 Mon Sep 17 00:00:00 2001 From: liumengyan Date: Tue, 12 May 2020 12:18:02 +0800 Subject: [PATCH] first add --- .gitignore | 8 + README.md | 3 + src/Makefile | 55 ++ src/gquic.h | 107 ++++ src/gquic_process.c | 1082 ++++++++++++++++++++++++++++++++++++++ src/gquic_process.h | 218 ++++++++ src/quic_analysis.c | 432 +++++++++++++++ src/quic_analysis.h | 78 +++ src/quic_callback.c | 106 ++++ src/quic_callback.h | 21 + src/quic_util.c | 210 ++++++++ src/quic_util.h | 40 ++ test/Makefile | 61 +++ test/dpkt_plug_gquic.cpp | 118 +++++ test/dpkt_plug_gquic.h | 25 + test/dpkt_plug_gquic.inf | 13 + test/gquic.h | 99 ++++ 17 files changed, 2676 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 src/Makefile create mode 100644 src/gquic.h create mode 100644 src/gquic_process.c create mode 100644 src/gquic_process.h create mode 100644 src/quic_analysis.c create mode 100644 src/quic_analysis.h create mode 100644 src/quic_callback.c create mode 100644 src/quic_callback.h create mode 100644 src/quic_util.c create mode 100644 src/quic_util.h create mode 100644 test/Makefile create mode 100644 test/dpkt_plug_gquic.cpp create mode 100644 test/dpkt_plug_gquic.h create mode 100644 test/dpkt_plug_gquic.inf create mode 100644 test/gquic.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f80a221 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +Debug +bin +*.o +*.d +*.so +.cproject +.project +.settings/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..96ee241 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# gquic + +gquic protocol parse plugin diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..351a835 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,55 @@ +CC = gcc +CCC = g++ +INCLUDES = -I/opt/MESA/include/ -I/home/sjzn/workspace/iquic_ngtcp2/openssl/build/include +LIB = -L./opt/MESA/lib/ -L/home/sjzn/workspace/iquic_ngtcp2/openssl/build/lib -lssl -lcrypto +#CFLAGS = -g3 -Wall -fPIC $(INCLUDES) +#CCCFLAGS = -std=c++11 -g3 -Wall -fPIC $(INCLUDES) +CFLAGS = -g3 -Wall -fPIC +CCCFLAGS = -std=c++11 -g3 -Wall -fPIC +TARGET = quic.so +INF = quic.inf +INSTALL_TARGET=$(TARGET) +LIB_FILE = $(wildcard ../lib/*.a) +SOURCES = $(wildcard *.c) $(wildcard gquic/*.c) +OBJECTS = $(SOURCES:.c=.o) +DEPS = $(SOURCES:.c=.d) + + +all:$(TARGET) +$(TARGET):$(OBJECTS) $(LIB_FILE) + $(CCC) -shared $(CFLAGS) $(OBJECTS) $(LIB) -o $@ + cp $(TARGET) ../bin/ + +%.o:%.c + $(CC) -c -o $@ $(CFLAGS) $< $(INCLUDES) + +%.o:%.cpp + $(CCC) -c -o $@ $(CCCFLAGS) $< $(INCLUDES) + +-include $(DEPS) + +clean : + rm -f $(OBJECTS) $(DEPS) $(TARGET) + +help: + @echo "-------OBJECTS--------" $(OBJECTS) + +PLUGIN_PATH=./plug/protocol +CONFLIST_NAME=conflist_protocol.inf +PLUGIN_DIR_NAME=quic +PLUGIN_INF_NAME=quic.inf +PAPP_PATH=/home/sjzn/gitFile/ceiec/sapp + +TARGET_DIR=$(PAPP_PATH)/$(PLUGIN_PATH)/$(PLUGIN_DIR_NAME)/ +INSERT_FILE=$(PAPP_PATH)/$(PLUGIN_PATH)/$(CONFLIST_NAME) +INSERT_CONTENT=$(PLUGIN_PATH)/$(PLUGIN_DIR_NAME)/$(PLUGIN_INF_NAME) +install: + mkdir -p $(TARGET_DIR) + cp -r ../bin/*.inf $(TARGET_DIR) + cp -r ../bin/*.so $(TARGET_DIR) + @ret=`cat $(INSERT_FILE)|grep $(INSERT_CONTENT)|wc -l`;if [ $$ret -eq 0 ];then echo $(INSERT_CONTENT) >>$(INSERT_FILE);fi + +CONF_DIR=$(PAPP_PATH)/conf/ +conf: + mkdir -p $(CONF_DIR) + cp -r ../bin/quic $(CONF_DIR) diff --git a/src/gquic.h b/src/gquic.h new file mode 100644 index 0000000..c03aeb0 --- /dev/null +++ b/src/gquic.h @@ -0,0 +1,107 @@ +/* + * quic.h + * + * Created on: 2019-4-4 + * Author: root + */ + +#ifndef SRC_GQUIC_H_ +#define SRC_GQUIC_H_ + + + +//#include +#include +#define MAX_EXTENSION_NUM 128 +#define MAX_TAG_VALUE_LEN 257 +#define SERVER_NAME_LEN 128 +//add in 20191207 +#define USER_AGENT_LEN 512 +#define RANDOM_LEN 32 +#define QUIC_VERSION_LEN 4 + + +#define QUIC_INTEREST_KEY (1< +#include +#include + + +#define C2S 0x01 +#define S2C 0x02 +#define GQUIC_HANDSHAKE_LEN 12+1+1+4+4 +#define DIVERSIFICATION_NONCE_LEN 32 + +enum gquic_type { + GQUIC=1, UNKNOWN_QUIC_TYPE +}; + +enum gquic_handshake_type { + QUIC_Crypto=1, UNKNOWN_HANDSHAKE_TYPE +}; + +//QUIC_DATA:is quic data pcap;QUIC_TRUE:is handshake pcap;QUIC_RETURN_DROPME:not quic protocol; +UCHAR is_handshake_pkt(struct quic_stream* a_quic_stream,uint32_t pkt_num_len, + char * quic_data, UINT32 quic_data_len, UINT32 offset){ + UINT8 frame_type = 0, num_timestamp, num_ranges, num_revived, num_blocks; + UINT32 len_stream = 0, len_offset = 0, len_data = 0, len_largest_observed = 0, len_missing_packet = 0; + if(!a_canRead(GQUIC_HANDSHAKE_LEN, quic_data_len, offset)){ + return QUIC_FALSE; + } + //message authentication hash + if(!a_canRead(MSG_AUTH_HASH_LEN, quic_data_len, offset)){ + return QUIC_FALSE; + } + offset += MSG_AUTH_HASH_LEN; + + //private flags + if(a_quic_stream->version > 0 && a_quic_stream->version < 34){ + offset += 1; + } + + while(offset < quic_data_len){ + frame_type = quic_data[offset]; + //offset+=1; + if(!(frame_type & FRAM_SPECIAL)){ + offset += 1; + UINT16 len_reason; + switch(frame_type){ + case PADDING: + return QUIC_FALSE; + break; + case RST_STREAM: + //stream id + offset += 4; + //Byte Offset + offset += 8; + //Error Code + offset += 4; + break; + case CONNECTION_CLOSE: + len_reason = 0; + //Error Code + offset += 4; + //Reason Phrase Length + if (get_remaining_len(quic_data_len, offset) <= 2){ + return QUIC_FALSE; + } + len_reason = a_pntoh16(quic_data, offset); + offset += 2; + //Reason Phrase,If length remaining == len_reason, it is Connection Close + if (get_remaining_len(quic_data_len, offset) == len_reason){ + return QUIC_DATA; + } + break; + case GOAWAY:{ + len_reason = 0; + //Error Code + offset += 4; + //Last Good Stream ID + offset += 4; + //Reason Phrase Length + if (get_remaining_len(quic_data_len, offset) <= 2){ + return QUIC_FALSE; + } + len_reason = a_pntoh16(quic_data, offset); + offset += 2; + //Reason Phrase + offset += len_reason; + } + break; + case WINDOW_UPDATE: + //Stream ID + offset += 4; + //Byte Offset + offset += 8; + break; + case BLOCKED: + //Stream ID + offset += 4; + break; + case STOP_WAITING: + //No longer Entropy after Q034 + if(a_quic_stream->version > 0 && a_quic_stream->version < 34){ + // Send Entropy + offset += 1; + } + //Least Unacked Delta + offset += pkt_num_len; + break; + case PING: //No Payload + default: + return QUIC_FALSE; + break; + } + }else{ + if(frame_type & STREAM){ + if(frame_type & STREAM_D){ + len_data = 2; + } + len_offset = read_offset_len(frame_type); + len_stream = read_stream_len(frame_type); + offset+=1; + offset+=len_stream; + offset+=len_offset; + offset+=len_data; + if (get_remaining_len(quic_data_len, offset) <= 4){ + return QUIC_FALSE; + } + UINT32 message_tag; + strncpy((char*)&message_tag, quic_data+offset, 4); + if(ntohl(message_tag) == CHLO || ntohl(message_tag) == SHLO || ntohl(message_tag) == REJ){ + return QUIC_TRUE; + } + }else if(frame_type & ACK){ + offset+=1; + len_largest_observed = read_largest_observed_len(frame_type); + len_missing_packet = read_missing_packet_len(frame_type); + //No longer Entropy after Q034 + if(a_quic_stream->version < 34 && a_quic_stream->version > 0){ + //Send Entropy + offset += 1; + offset += len_largest_observed; + offset += 2; //ack delay time + if(get_remaining_len(quic_data_len, offset) <= 1){ + return QUIC_FALSE; + } + strncpy((char*)&num_timestamp, quic_data+offset,1); + offset += 1; + if(num_timestamp > 0){ + offset += 1; + offset += 4; //first timestamp + offset += (num_timestamp - 1)*(1+2); + } + if(frame_type & ACK_N){ + //Num Ranges + if (get_remaining_len(quic_data_len, offset) <= 1){ + return QUIC_FALSE; + } + strncpy((char*)&num_ranges, quic_data+offset,1); + offset += 1; + + //Num Range x (Missing Packet + Range Length) + offset += num_ranges*(len_missing_packet+1); + + //Num Revived + if (get_remaining_len(quic_data_len, offset) <= 1){ + return QUIC_FALSE; + } + strncpy((char*)&num_revived, quic_data+offset,1); + offset += 1; + //Num Revived x Length Largest Observed + offset += num_revived*len_largest_observed; + } + }else{ + //Largest Acked + offset += len_largest_observed; + //Largest Acked Delta Time + offset += 2; + //Ack Block + if(frame_type & ACK_N){ + if (get_remaining_len(quic_data_len, offset) <= 1){ + return QUIC_FALSE; + } + strncpy((char*)&num_blocks, quic_data+offset,1); + offset += 1; + } + //First Ack Block Length + offset += len_missing_packet; + if(num_blocks){ + //Gap to next block + offset += 1; + num_blocks -= 1; + offset += (num_blocks - 1)*len_missing_packet; + } + //Timestamp + if (get_remaining_len(quic_data_len, offset) <= 1){ + return QUIC_FALSE; + } + strncpy((char*)&num_timestamp, quic_data+offset,1); + offset += 1; + if(num_timestamp > 0){ + //Delta Largest Acked + offset += 1; + //Time Since Largest Acked + offset += 4; + //Num Timestamp x (Delta Largest Acked + Time Since Previous Timestamp) + offset += (num_timestamp - 1)*(1+2); + } + } + }else{ + offset +=1; + return QUIC_FALSE; + } + } + } + return QUIC_FALSE; +} + +void gquic_proc_tag(struct streaminfo *pstream, struct quic_stream *a_quic_stream, UINT16 tag_num, UINT8 direction, + unsigned long long region_flag, int thread_seq, void* a_packet, char * quic_data, UINT32 quic_data_len, UINT32 g_pos_t){ + UINT32 total_tag_len = 0, tag_len = 0; + UINT32 tag_value_start = tag_num * 4 * 2 + g_pos_t; + UINT32 tag_offset_end = 0, pre_tag_offset_end = 0; + UCHAR return_val; + int tag_type_len = 4, tag_offset_len = 4, num = 0; + + + while(tag_num > 0 && a_canRead(tag_type_len + tag_offset_len, quic_data_len, g_pos_t)){ + UINT32 tag_type; + if(!a_canRead(tag_type_len, quic_data_len, g_pos_t)){ + return; + } + + tag_type = a_pntoh32(quic_data, g_pos_t); + g_pos_t += 4; + if(!a_canRead(tag_type_len, quic_data_len, g_pos_t)){ + return; + } + tag_offset_end = a_pletoh32(quic_data, g_pos_t); + if(tag_offset_end < pre_tag_offset_end){ + return; + } + if(tag_offset_end >= quic_data_len) { + return ; + } + g_pos_t += 4; + tag_len = tag_offset_end - pre_tag_offset_end; + if(!a_canRead(tag_len, quic_data_len, tag_value_start)){ + return ; + } + total_tag_len += tag_len; + if(tag_len == 0){ + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + continue; + } + if(tag_type == TAG_PAD){ + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + continue; + } + //common_cert + if(tag_type == TAG_CCS){ + if(a_quic_stream->common_cert.ptr_value == NULL){ + a_quic_stream->common_cert.ptr_value = (char *)dictator_malloc(thread_seq, sizeof(char)*tag_len); + memset(a_quic_stream->common_cert.ptr_value, 0, tag_len); + a_quic_stream->common_cert.length = tag_len; + memcpy(a_quic_stream->common_cert.ptr_value, quic_data + tag_value_start, tag_len); + if(a_quic_stream->common_cert.ptr_value != NULL){ + return_val = quic_proc_interest_region(QUIC_COMM_CERT_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } + } + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + continue; + } + //cached_cert + if(tag_type == TAG_CCRT){ + if(a_quic_stream->cached_cert.ptr_value == NULL){ + a_quic_stream->cached_cert.ptr_value = (char *)dictator_malloc(thread_seq, sizeof(char)*tag_len); + memset(a_quic_stream->cached_cert.ptr_value, 0, tag_len); + a_quic_stream->cached_cert.length = tag_len; + memcpy(a_quic_stream->cached_cert.ptr_value, quic_data + tag_value_start, tag_len); + if(a_quic_stream->cached_cert.ptr_value != NULL){ + return_val = quic_proc_interest_region(QUIC_CACHED_CERT_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } + } + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + continue; + } + //cert_chain?????length need change + if(tag_type == TAG_CRT){ + if(a_quic_stream->cert_chain.length == 0 && a_quic_stream->cert_chain.ptr_value == NULL){ + a_quic_stream->cert_chain.length = tag_len > (quic_data_len-tag_value_start+1) ? (quic_data_len-tag_value_start+1) : tag_len; + a_quic_stream->cert_chain.ptr_value = (char *)dictator_malloc(thread_seq, a_quic_stream->cert_chain.length); + memset(a_quic_stream->cert_chain.ptr_value, 0, a_quic_stream->cert_chain.length); + memcpy(a_quic_stream->cert_chain.ptr_value, quic_data + tag_value_start, a_quic_stream->cert_chain.length); + tag_num--; + tag_value_start += a_quic_stream->cert_chain.length; + pre_tag_offset_end = tag_offset_end; + if(a_quic_stream->cert_chain.ptr_value != NULL){ + return_val = quic_proc_interest_region(QUIC_CERT_CHAIN_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } + }else{ + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + } + continue; + } + if(tag_type == TAG_SNI){ + if(a_quic_stream->st_client_hello.server_name_len ==0){ + assert(tag_len < SERVER_NAME_LEN); + a_quic_stream->st_client_hello.server_name_len = tag_len > SERVER_NAME_LEN ? SERVER_NAME_LEN : tag_len; + strncpy(a_quic_stream->st_client_hello.server_name, quic_data + tag_value_start, tag_len); + a_quic_stream->st_client_hello.server_name_len = tag_len; +// printf("SNI:%s\n",a_quic_stream->st_client_hello.server_name); + } + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + continue; + } + if(tag_type == TAG_UAID){ + assert(tag_len < USER_AGENT_LEN); + if(a_quic_stream->st_client_hello.user_agent_len==0){ + a_quic_stream->st_client_hello.user_agent_len = tag_len > USER_AGENT_LEN ? USER_AGENT_LEN : tag_len; + strncpy(a_quic_stream->st_client_hello.user_agent, quic_data + tag_value_start, a_quic_stream->st_client_hello.user_agent_len); + +// printf("UA:%s\n",a_quic_stream->st_client_hello.user_agent); + } + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + continue; + } + + if(direction == 0x01 && num < a_quic_stream->st_client_hello.ext_tag_num){ + a_quic_stream->st_client_hello.ext_tags[num]->type = tag_type; + a_quic_stream->st_client_hello.ext_tags[num]->length = tag_len > MAX_TAG_VALUE_LEN-1 ? tag_len > MAX_TAG_VALUE_LEN-1 : tag_len; + memcpy(a_quic_stream->st_client_hello.ext_tags[num]->ptr_value, quic_data+tag_value_start, a_quic_stream->st_client_hello.ext_tags[num]->length); +// a_readBytes(a_quic_stream->st_client_hello.ext_tags[num]->ptr_value, +// a_quic_stream->st_client_hello.ext_tags[num]->length, quic_data, quic_data_len, &tag_value_start); + ((unsigned char*)(a_quic_stream->st_client_hello.ext_tags[num]->ptr_value))[MAX_TAG_VALUE_LEN-1] = '\0'; + + }else if(num < a_quic_stream->st_server_hello.ext_tag_num){ + a_quic_stream->st_server_hello.ext_tags[num]->type = tag_type; + a_quic_stream->st_server_hello.ext_tags[num]->length = tag_len > MAX_TAG_VALUE_LEN-1 ? tag_len > MAX_TAG_VALUE_LEN-1 : tag_len; + memcpy(a_quic_stream->st_server_hello.ext_tags[num]->ptr_value, quic_data+tag_value_start, a_quic_stream->st_server_hello.ext_tags[num]->length); +// a_readBytes(a_quic_stream->st_server_hello.ext_tags[num]->ptr_value, +// a_quic_stream->st_server_hello.ext_tags[num]->length, quic_data, quic_data_len, &tag_value_start); + ((unsigned char*)(a_quic_stream->st_server_hello.ext_tags[num]->ptr_value))[MAX_TAG_VALUE_LEN-1] = '\0'; + } + num++; + tag_num--; + tag_value_start += tag_len; + pre_tag_offset_end = tag_offset_end; + } + g_pos_t = tag_value_start; + return; +} + +//frame type->stream->offset->data length +void gquic_proc_unencrypt(struct streaminfo *pstream, struct quic_stream* a_quic_stream, uint32_t pkt_num_len, + unsigned long long region_flag, int thread_seq, void* a_packet, char * quic_data, UINT32 quic_data_len, UINT32 g_pos_t){ + UINT8 frame_type, num_timestamp, num_ranges, num_revived, num_blocks; + UINT32 len_largest_observed = 0, len_missing_packet = 0; + + g_pos_t += MSG_AUTH_HASH_LEN; + //private flags + if(a_quic_stream->version <34){ + g_pos_t += 1; + } + while(g_pos_t < quic_data_len){ + a_readUInt8(&frame_type, quic_data, quic_data_len, &g_pos_t); + if(!(frame_type & FRAM_SPECIAL)){ + g_pos_t += 1; + UINT16 len_reason; + switch(frame_type){ + case PADDING: + return; + break; + case RST_STREAM: + //stream id + g_pos_t += 4; + //Byte Offset + g_pos_t += 8; + //Error Code + g_pos_t += 4; + a_quic_stream->fin_flag = QUIC_TRUE; + break; + case CONNECTION_CLOSE: + len_reason = 0; + //Error Code + g_pos_t += 4; + //Reason Phrase Length + len_reason = a_pntoh16(quic_data, g_pos_t); + g_pos_t += 2; + //Reason Phrase,If length remaining == len_reason, it is Connection Close + if (get_remaining_len(quic_data_len, g_pos_t) == len_reason){ + return; + } + if(a_quic_stream->fin_flag == QUIC_FALSE){ + a_quic_stream->fin_flag = QUIC_HALF_CLOSE; + }else{ + a_quic_stream->fin_flag = QUIC_TRUE; + } + break; + case GOAWAY:{ + len_reason = 0; + //Error Code + g_pos_t += 4; + //Last Good Stream ID + g_pos_t += 4; + //Reason Phrase Length + len_reason = a_pntoh16(quic_data, g_pos_t); + g_pos_t += 2; + //Reason Phrase + g_pos_t += len_reason; + } + break; + case WINDOW_UPDATE: + //Stream ID + g_pos_t += 4; + //Byte Offset + g_pos_t += 8; + break; + case BLOCKED: + //Stream ID + g_pos_t += 4; + break; + case STOP_WAITING: + //No longer Entropy after Q034 + if(a_quic_stream->version < 34){ + // Send Entropy + g_pos_t += 1; + } + //Least Unacked Delta + g_pos_t += pkt_num_len; + break; + case PING: //No Payload + default: + return; + break; + } + }else{ + //special packet + if(frame_type & STREAM){ + UINT8 len_data = 0, len_stream = 0, len_offset = 0, return_val; + UINT16 tag_num = 0; + UINT32 stream_id, message_tag; + if(frame_type & STREAM_F){ + a_quic_stream->fin_flag = QUIC_TRUE; + } + if(frame_type & STREAM_D){ + len_data = 2; + } + len_stream = read_stream_len(frame_type); + stream_id = get_stream_id(quic_data, g_pos_t, len_stream); + g_pos_t += len_stream; + + len_offset = read_offset_len(frame_type); + g_pos_t += len_offset; + + g_pos_t += len_data; + //handshake + if(stream_id == 1){ + message_tag = a_pntoh32((void *)quic_data, g_pos_t); + g_pos_t += 4; + tag_num = a_pletoh16(quic_data, g_pos_t); + g_pos_t += 2; //tag_num + g_pos_t += 2; //padding + switch(message_tag){ + case CHLO: + //MTAG_CHLO; + if(a_quic_stream->st_client_hello.ext_tags == NULL){ +// a_quic_stream->st_client_hello = (struct quic_client_hello*)dictator_malloc(thread_seq,sizeof(struct quic_client_hello)); +// memset(a_quic_stream->st_client_hello, 0, sizeof(struct quic_client_hello)); + quic_init_clientHello(&a_quic_stream->st_client_hello, tag_num, thread_seq); + }else if(a_quic_stream->st_server_hello.ext_tag_num){ + if(tag_num > a_quic_stream->st_client_hello.ext_tag_num){ +// a_quic_stream->is_0rtt = QUIC_TRUE; + quic_release_clientHello(thread_seq, &a_quic_stream->st_client_hello); + quic_init_clientHello(&a_quic_stream->st_client_hello, tag_num, thread_seq); + }else{ + return; + } + }else{ + return; + } + gquic_proc_tag(pstream, a_quic_stream, tag_num, C2S, region_flag, thread_seq, a_packet, quic_data, quic_data_len, g_pos_t); + if(a_quic_stream->st_client_hello.server_name_len > 0 || a_quic_stream->st_client_hello.user_agent_len > 0){ + quic_proc_interest_region(QUIC_CLIENT_HELLO_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } + +// if(return_val != QUIC_RETURN_NORM){ +// return return_val; +// } + break; + case SHLO: + //MTAG_SHLO; + if(a_quic_stream->st_server_hello.ext_tags == NULL){ +// a_quic_stream->st_server_hello = (struct quic_server_hello*)dictator_malloc(thread_seq,sizeof(struct quic_server_hello)); +// memset(a_quic_stream->st_server_hello, 0, sizeof(struct quic_server_hello)); + quic_init_serverHello(&a_quic_stream->st_server_hello, tag_num, thread_seq); + }else{ + return; + } + gquic_proc_tag(pstream, a_quic_stream, tag_num, S2C, region_flag, thread_seq, a_packet, quic_data, quic_data_len, g_pos_t); + + if(a_quic_stream->st_server_hello.ext_tags != NULL){ + quic_proc_interest_region(QUIC_SERVER_HELLO_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } +// if(return_val != QUIC_RETURN_NORM){ +// return return_val; +// } + break; + case REJ: + //MTAG_REJ; + if(a_quic_stream->st_server_hello.ext_tags == NULL){ +// a_quic_stream->st_server_hello = (struct quic_server_hello*)dictator_malloc(thread_seq,sizeof(struct quic_server_hello)); +// memset(a_quic_stream->st_server_hello, 0, sizeof(struct quic_server_hello)); + quic_init_serverHello(&a_quic_stream->st_server_hello, tag_num, thread_seq); + }else{ + return; + } + gquic_proc_tag(pstream, a_quic_stream, tag_num, S2C, region_flag, thread_seq, a_packet, quic_data, quic_data_len, g_pos_t); + if(a_quic_stream->st_server_hello.ext_tags != NULL){ + quic_proc_interest_region(QUIC_SERVER_HELLO_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } +// if(return_val != QUIC_RETURN_NORM){ +// return return_val; +// } + break; + default: + break; + } + } + }else if(frame_type & ACK){ + g_pos_t+=1; + len_largest_observed = read_largest_observed_len(frame_type); + len_missing_packet = read_missing_packet_len(frame_type); + //No longer Entropy after Q034 + if(a_quic_stream->version < 34){ + //Send Entropy + g_pos_t += 1; + g_pos_t += len_largest_observed; + g_pos_t += 2; //ack delay time + strncpy((char*)&num_timestamp, quic_data+g_pos_t,1); + g_pos_t += 1; + if(num_timestamp > 0){ + g_pos_t += 1; + g_pos_t += 4; + g_pos_t += (num_timestamp - 1)*(1+2); + } + if(frame_type & ACK_N){ + strncpy((char*)&num_ranges, quic_data+g_pos_t,1); + g_pos_t += 1; + g_pos_t += num_ranges*(len_missing_packet+1); + strncpy((char*)&num_revived, quic_data+g_pos_t,1); + g_pos_t += 1; + //Num Revived x Length Largest Observed + g_pos_t += num_revived*len_largest_observed; + } + }else{ + //Largest Acked + g_pos_t += len_largest_observed; + //Largest Acked Delta Time + g_pos_t += 2; + //Ack Block + if(frame_type & ACK_N){ + strncpy((char*)&num_blocks, quic_data+g_pos_t,1); + g_pos_t += 1; + } + //First Ack Block Length + g_pos_t += len_missing_packet; + if(num_blocks){ + //Gap to next block + g_pos_t += 1; + num_blocks -= 1; + g_pos_t += (num_blocks - 1)*len_missing_packet; + } + //Timestamp + strncpy((char*)&num_timestamp, quic_data+g_pos_t,1); + g_pos_t += 1; + if(num_timestamp > 0){ + //Delta Largest Acked + g_pos_t += 1; + //Time Since Largest Acked + g_pos_t += 4; + //Num Timestamp x (Delta Largest Acked + Time Since Previous Timestamp) + g_pos_t += (num_timestamp - 1)*(1+2); + } + } + }else{ + g_pos_t +=1; + return; + } + } + } + return; +} + +UINT8 parse_gquic_Q046(struct streaminfo *pstream, unsigned long long region_flag, void* a_packet, + int thread_seq, const char * payload, uint32_t payload_len, struct quic_stream* a_quic_stream){ + uint32_t g_pos_t = 0; + if (!a_canRead(5, payload_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + uint32_t version; + g_pos_t += 1; + strncpy((char*)&version, payload+g_pos_t, 4); + if(ntohl(version) != VER_Q046){ + return QUIC_RETURN_DROPME; + } + g_pos_t += 2; + a_quic_stream->version = (payload[g_pos_t] & 0x0f) * 10 + (payload[g_pos_t+1] & 0x0f); + a_quic_stream->is_quic_stream = QUIC_TRUE; + quic_proc_interest_region(QUIC_VERSION_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + g_pos_t += 2; + if (!a_canRead(25, payload_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + g_pos_t += 25; + uint8_t frame_type; + while(g_pos_t < payload_len){ + a_readUInt8(&frame_type, payload, payload_len, &g_pos_t); + if(frame_type & STREAM){ + uint8_t len_data = 0, len_stream = 0, len_offset = 0; + uint16_t tag_num = 0; + uint32_t stream_id, message_tag; + if(frame_type & STREAM_D){ + len_data = 2; + } + len_stream = read_stream_len(frame_type); + stream_id = get_stream_id(payload, g_pos_t, len_stream); + g_pos_t += len_stream; + + len_offset = read_offset_len(frame_type); + g_pos_t += len_offset; + + g_pos_t += len_data; + if(stream_id == 1){ + message_tag = a_pntoh32((void *)payload, g_pos_t); + g_pos_t += 4; + tag_num = a_pletoh16(payload, g_pos_t); + g_pos_t += 2; //tag_num + g_pos_t += 2; //padding + char sni[1024]; + uint32_t sni_len = 0; + char uaid[1024]; + uint32_t uaid_len = 0; + switch(message_tag){ + case CHLO: + //MTAG_CHLO; + if(a_quic_stream->st_client_hello.ext_tags == NULL){ + quic_init_clientHello(&a_quic_stream->st_client_hello, tag_num, thread_seq); + } + gquic_proc_tag(pstream, a_quic_stream, tag_num, C2S, region_flag, thread_seq, a_packet, payload, payload_len, g_pos_t); + if(a_quic_stream->st_client_hello.server_name_len > 0 || a_quic_stream->st_client_hello.user_agent_len > 0){ + quic_proc_interest_region(QUIC_CLIENT_HELLO_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } +// *chello = (struct quic_pme *)malloc(sizeof(struct quic_pme) + sni_len + uaid_len + 2); +// memset(*chello, 0, sizeof(struct quic_pme) + sni_len + uaid_len + 2); + +// *chello = (struct quic_pme *)malloc(sizeof(struct quic_pme)); +// memset(*chello, 0, sizeof(struct quic_pme)); + + +// if(sni_len > 128){ +// sni_len = GQUIC_SNI_LEN; +// } +// a_quic_stream->st_client_hello->server_name_len = sni_len; +// memcpy((chello)->sni, sni, sni_len); +// (chello)->sni[127] = '\0'; +// if(uaid_len > 512){ +// uaid_len = GQUIC_UAID_LEN; +// } +// (chello)->user_agent_len = uaid_len; +// memcpy((chello)->user_agent, uaid, uaid_len); +// (chello)->user_agent[511] = '\0'; + +// char * p, *q; +// p = (char*)(*chello) + sizeof(struct quic_pme); +// q = (char*)(*chello) + sizeof(struct quic_pme) + sni_len + 1; +// memcpy(p, sni, sni_len); +// memset(p+sni_len, '\0', 1); +// (*chello)->sni = p; +// memcpy(q, uaid, uaid_len); +// memset(q+uaid_len, '\0', 1); +// (*chello)->user_agent = q; +// printf("46 chello_sni_len:%d, chello_sni:%s\n",(*chello)->sni_len, (*chello)->sni); +// printf("46 chello_uaid_len:%d, chello_uaid:%s\n",(*chello)->user_agent_len, (*chello)->user_agent); + break; + default: + break; + } + } + } + } + return QUIC_RETURN_NORM; +} + +UINT8 parse_gquic(struct streaminfo *pstream, unsigned long long region_flag, void* a_packet, + int thread_seq, const char * payload, uint32_t payload_len, struct quic_stream* a_quic_stream){ + uint8_t pub_flags = 0; + uint8_t nonce_flag = 0; + uint8_t reset_flag = 0; + uint8_t version_flag = 0; + int ret = QUIC_RETURN_DROPME; + uint32_t g_pos_t = 0; + uint64_t connection_id = 0; + int connection_id_len = 0; + uint32_t pkt_num = 0; + uint32_t pkt_num_len = 0; + uint32_t version; + strncpy((char *)&pub_flags, payload + g_pos_t, 1); + g_pos_t += 1; + if (pub_flags > PACKET_PUBLIC_FLAGS_MAX) { + return QUIC_RETURN_DROPME; + } + nonce_flag = (pub_flags & PUBLIC_FLAG_NONCE) != 0; + reset_flag = (pub_flags & PUBLIC_FLAG_RST) != 0; + version_flag = (pub_flags & PUBLIC_FLAG_VER) != 0; + if (reset_flag && version_flag) { + return QUIC_RETURN_DROPME; + } + if(reset_flag){ + return QUIC_RETURN_DROPME; + } + connection_id_len = read_conn_id_len(pub_flags); + if(connection_id_len == -1){ + return QUIC_RETURN_DROPME; + }else if(connection_id_len == 0){ + connection_id = 0; + }else{ + if (!a_canRead(connection_id_len, payload_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + connection_id = a_pntoh64((void *)payload, g_pos_t); + g_pos_t += connection_id_len; + } + pkt_num_len = read_seq_num_len(pub_flags); + if (!a_canRead(VERSION_LEN, payload_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + if(payload[g_pos_t] != PUBLIC_FLAG_VER_FST_BYTE){ + return QUIC_RETURN_DROPME; + } + g_pos_t += 2; + version = (payload[g_pos_t] & 0x0f) * 10 + (payload[g_pos_t+1] & 0x0f); + a_quic_stream->version = version; + quic_proc_interest_region(QUIC_VERSION_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + + g_pos_t += 2; + if (!a_canRead(pkt_num_len, payload_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + pkt_num = get_pkn(payload, g_pos_t, pkt_num_len); + g_pos_t += pkt_num_len; + //version 协商 + if(!version_flag && a_quic_stream->version && !a_quic_stream->version_cfm){ + a_quic_stream->version_cfm = QUIC_TRUE; + quic_proc_interest_region(QUIC_VERSION_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + } + ret = is_handshake_pkt(a_quic_stream, pkt_num_len, payload, payload_len, g_pos_t); + + if(ret == QUIC_TRUE){ + //handshake + if(!a_quic_stream->is_quic_stream){ + a_quic_stream->is_quic_stream = QUIC_TRUE; + } + gquic_proc_unencrypt(pstream, a_quic_stream, pkt_num_len, region_flag, thread_seq, a_packet, payload, payload_len, g_pos_t); + ret = QUIC_RETURN_NORM; + }else if(ret == QUIC_DATA){ + //ack or special stream + a_quic_stream->is_quic_stream = QUIC_TRUE; + ret = QUIC_RETURN_NORM; + }else{ + //gquic data or not gquic packet + if(a_quic_stream->is_quic_stream){ + quic_proc_interest_region(QUIC_APPLICATION_DATA_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + ret = QUIC_RETURN_NORM; + }else{ + ret = QUIC_RETURN_DROPME; + } + } + return ret; +} + + + + +//cid->version->nounce->pkt num->ahn hash(12) +UINT8 gquic_process(struct streaminfo *pstream, struct quic_stream* a_quic_stream, + unsigned long long region_flag, int thread_seq, void* a_packet, char* quic_data, UINT32 quic_data_len) { + + int ret = parse_gquic(pstream, region_flag, a_packet, thread_seq, quic_data, quic_data_len, a_quic_stream); + if(ret == QUIC_RETURN_DROPME){ + ret = parse_gquic_Q046(pstream, region_flag, a_packet, thread_seq, quic_data, quic_data_len, a_quic_stream); + } + return ret; + +/* + + UINT8 pub_flags; + UCHAR return_val = QUIC_RETURN_NORM; + UINT32 g_pos_t = 0; + strncpy((char *)&pub_flags, quic_data + g_pos_t, 1); + g_pos_t += 1; + if (pub_flags > PACKET_PUBLIC_FLAGS_MAX) { + return QUIC_RETURN_DROPME; + } + struct gquic_pkt_hdr gquic_hdr = {}; + memset(&gquic_hdr, 0, sizeof(struct gquic_pkt_hdr)); + gquic_hdr.nonce_flag = (pub_flags & PUBLIC_FLAG_NONCE) != 0; + gquic_hdr.reset_flag = (pub_flags & PUBLIC_FLAG_RST) != 0; + gquic_hdr.version_flag = (pub_flags & PUBLIC_FLAG_VER) != 0; + if (gquic_hdr.reset_flag && gquic_hdr.version_flag) { + return QUIC_RETURN_DROPME; + } + if(gquic_hdr.reset_flag){ + return QUIC_RETURN_DROPME; + } + gquic_hdr.connection_id_len = read_conn_id_len(pub_flags); + if(gquic_hdr.connection_id_len == -1){ + return QUIC_RETURN_DROPME; + }else if(gquic_hdr.connection_id_len == 0){ + gquic_hdr.connection_id = 0; + }else{ + if (!a_canRead(gquic_hdr.connection_id_len, quic_data_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + if(a_quic_stream->gquic_cID == 0){ + gquic_hdr.connection_id = a_pntoh64((void *)quic_data, g_pos_t); + a_quic_stream->gquic_cID = gquic_hdr.connection_id; + } + + g_pos_t+=gquic_hdr.connection_id_len; + } + if(gquic_hdr.nonce_flag && pstream->curdir == 0x02){ + g_pos_t+=DIVERSIFICATION_NONCE_LEN; + } + gquic_hdr.packet_number_len = read_seq_num_len(pub_flags); + if (gquic_hdr.version_flag) { + //c2s + if(pstream->curdir == 0x01){ + if (!a_canRead(4, quic_data_len, g_pos_t)) { + return QUIC_RETURN_DROPME; + } + if(quic_data[g_pos_t] != PUBLIC_FLAG_VER_FST_BYTE){ + return QUIC_RETURN_DROPME; + } + g_pos_t += 2; + a_quic_stream->version_flag = QUIC_TRUE; + gquic_hdr.version = (quic_data[g_pos_t] & 0x0f) * 10 + (quic_data[g_pos_t+1] & 0x0f); + g_pos_t += 2; + a_quic_stream->version = gquic_hdr.version; + printf("VERSION:%d\n",a_quic_stream->version); + } + } + + if(!gquic_hdr.version_flag && pstream->curdir == 0x02 && a_quic_stream->version_flag == QUIC_TRUE){ + a_quic_stream->version_flag = QUIC_FALSE; + return_val = quic_proc_interest_region(QUIC_VERSION_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); +// if(return_val != QUIC_RETURN_NORM){ +// char info[256]; +// sprintf(info, "VERSION CALLBACK ERROR\t%s_%s_%d\t", __FILE__, __FUNCTION__, __LINE__); +// printf("%s\n", info); +// return return_val; +// } + } + if(!a_canRead(gquic_hdr.packet_number_len, quic_data_len, g_pos_t)){ + return QUIC_RETURN_DROPME; + } + UINT32 pkt_num = get_pkn(quic_data, g_pos_t, gquic_hdr.packet_number_len); + gquic_hdr.packet_number = pkt_num; + g_pos_t += gquic_hdr.packet_number_len; + + char sip[32],dip[32]; + memset(sip, 0, sizeof(sip)); + memset(dip, 0, sizeof(dip)); + a_ntoa(pstream->addr.tuple4_v4->saddr, sip); + a_ntoa(pstream->addr.tuple4_v4->daddr, dip); + + return_val = is_handshake_pkt(a_quic_stream, &gquic_hdr, quic_data, quic_data_len, g_pos_t); + if(return_val == QUIC_TRUE){ + //handshake + if(!a_quic_stream->is_quic_stream){ + a_quic_stream->is_quic_stream = QUIC_TRUE; + } + gquic_proc_unencrypt(pstream, &gquic_hdr, a_quic_stream, region_flag, thread_seq, a_packet, quic_data, quic_data_len, g_pos_t); + return_val = QUIC_RETURN_NORM; + }else if(return_val == QUIC_DATA){ + //ack or special stream + if(!a_quic_stream->is_quic_stream){ + a_quic_stream->is_quic_stream = QUIC_TRUE; + } + }else{ + //gquic data or not gquic packet + if(a_quic_stream->is_quic_stream){ + return_val = quic_proc_interest_region(QUIC_APPLICATION_DATA_MASK, &a_quic_stream, pstream, region_flag, thread_seq, a_packet); + }else{ + return_val = QUIC_RETURN_DROPME; + } + } + +// if(a_quic_stream->type == GQUIC){ +// if(pstream->curdir == 0x01){ +// printf("QUIC\tC2S\tSIP=%s\tDIP=%s\tPKN=%d\tVERSION=%d\tthread_seq=%d\n",sip,dip,pkt_num,gquic_hdr.version,thread_seq); +// }else{ +// printf("QUIC\tS2C\tSIP=%s\tDIP=%s\tPKN=%d\tVERSION=%d\tthread_seq=%d\n",sip,dip,pkt_num,gquic_hdr.version,thread_seq); +// } +// } +// else{ +// if(pstream->curdir == 0x01){ +// printf("UNKN\tC2S\tSIP=%s\tDIP=%s\tPKN=%d\tVERSION=%d\tthread_seq=%d\n",sip,dip,pkt_num,gquic_hdr.version,thread_seq); +// }else{ +// printf("UNKN\tS2C\tSIP=%s\tDIP=%s\tPKN=%d\tVERSION=%d\tthread_seq=%d\n",sip,dip,pkt_num,gquic_hdr.version,thread_seq); +// } +// } + return return_val; + */ +} + + +UINT32 read_offset_len(UINT8 frame_type){ + switch((frame_type & STREAM_OOO) >> 2){ + case 0: + return 0; + break; + case 1: + return 2; + break; + case 2: + return 3; + break; + case 3: + return 4; + break; + case 4: + return 5; + break; + case 5: + return 6; + break; + case 6: + return 7; + break; + case 7: + return 8; + break; + default: + break; + } + return 0; +} + +UINT32 read_stream_len(UINT8 frame_type){ + UINT32 stream_len = 0; + switch(frame_type & STREAM_SS){ + case STREAM_ID_1BYTE: + stream_len = 1; + break; + case STREAM_ID_2BYTE: + stream_len = 2; + break; + case STREAM_ID_3BYTE: + stream_len = 3; + break; + case STREAM_ID_4BYTE: + stream_len = 4; + break; + default: + break; + } + return stream_len; +} + +int read_conn_id_len(UINT8 flags) { + switch (flags & BYTE_CNTID_8) { + case BYTE_CNTID_8: + return 8; + case BYTE_CNTID_0: + return 0; + default: + return -1; + } +} + +UINT32 read_seq_num_len(UINT8 flags) { + switch (flags & PKT_NUM_6) { + case PKT_NUM_6: + return 6; + case PKT_NUM_4: + return 4; + case PKT_NUM_2: + return 2; + case PKT_NUM_1: + return 1; + default: + break; + } + return 1; +} + + +UINT32 read_largest_observed_len(UINT8 frame_type){ + switch((frame_type & ACK_LL) >> 2){ + case 0: + return 1; + break; + case 1: + return 2; + break; + case 2: + return 4; + break; + case 3: + return 6; + break; + default: + break; + } + return 1; +} + +UINT32 read_missing_packet_len(UINT8 frame_type){ + switch(frame_type & ACK_MM){ + case 0: + return 1; + break; + case 1: + return 2; + break; + case 2: + return 4; + break; + case 3: + return 6; + break; + default: + break; + } + return 1; +} + + + +UINT32 get_stream_id(char* g_data_t, UINT32 offset, UINT8 stream_id_len){ + if(stream_id_len == 1){ + return g_data_t[offset]; + }else if(stream_id_len == 2){ + return a_pletoh16((void *)g_data_t, offset); + }else if(stream_id_len == 3){ + return a_pletoh24((void *)g_data_t, offset); + }else{ + return a_pletoh32((void *)g_data_t, offset); + } +} + +UINT32 get_pkn(char* g_data_t, UINT32 offset, UINT8 pkn_len){ + if(pkn_len == 1){ + return g_data_t[offset]; + }else if(pkn_len == 2){ + return a_pletoh16((void *)g_data_t, offset); + }else if(pkn_len == 4){ + return a_pletoh32((void *)g_data_t, offset); + }else{//6 + return a_pletoh48((void *)g_data_t, offset); + } +} diff --git a/src/gquic_process.h b/src/gquic_process.h new file mode 100644 index 0000000..5091c2f --- /dev/null +++ b/src/gquic_process.h @@ -0,0 +1,218 @@ +/* + * gquic_process.h + * + * Created on: 2019锟斤拷4锟斤拷2锟斤拷 + * Author: root + */ + +#ifndef SRC_GQUIC_GQUIC_PROCESS_H_ +#define SRC_GQUIC_GQUIC_PROCESS_H_ + +#include +#include +#include + +#include "gquic.h" + +#define VERSION_LEN 4 +#define VER_Q046 0x51303436 +/**************************************************************************/ +/* Public flag */ +/**************************************************************************/ + + +#define PACKET_PUBLIC_FLAGS_MAX 0x7f +#define PUBLIC_FLAG_VER_FST_BYTE 0x51 +#define PUBLIC_FLAG_VER 0x01 +#define PUBLIC_FLAG_RST 0x02 +#define PUBLIC_FLAG_NONCE 0x04 +#define BYTE_CNTID_8 0x08 +#define BYTE_CNTID_0 0x00 +enum gquic_connid_len { + PACKET_0BYTE_CONNECTION_ID = 0, + PACKET_8BYTE_CONNECTION_ID = 8 +}; + +#define PKT_NUM_6 0x30 +#define PKT_NUM_4 0x20 +#define PKT_NUM_2 0x10 +#define PKT_NUM_1 0x00 + +//enum gquic_pkt_num_len { +// PACKET_1BYTE_PACKET_NUMBER = 1, +// PACKET_2BYTE_PACKET_NUMBER = 2, +// PACKET_4BYTE_PACKET_NUMBER = 4, +// PACKET_6BYTE_PACKET_NUMBER = 6 +//}; + +// Used to indicate a QuicSequenceNumberLength using two flag bits. +enum gquic_pkt_num_len_flags { + PACKET_FLAGS_1BYTE_PACKET = 0, // 00 + PACKET_FLAGS_2BYTE_PACKET = 1, // 01 + PACKET_FLAGS_4BYTE_PACKET = 1 << 1, // 10 + PACKET_FLAGS_6BYTE_PACKET = 1 << 1 | 1, // 11 +}; + +//#define PUBLIC_FLAG_MULTIPATH 0x40 +#define UNUSE 0x80 +#define MSG_AUTH_HASH_LEN 12 +#define PUB_HEAD_SEQ_SFT 4 + +/**************************************************************************/ +/* Frame type */ +/**************************************************************************/ +#define FRAM_SPECIAL 0xE0 +#define STREAM 0x80 +#define STREAM_F 0x40 //fin +#define STREAM_D 0x20 //data length +#define STREAM_OOO 0x1C //offset length +#define STREAM_SS 0x03 //stream length +#define ACK 0x40 +#define ACK_LL 0x0c +#define ACK_MM 0x03 +#define ACK_N 0x20 +#define CONGESTION_FEEDBACK 0x20 +#define PADDING 0x00 +#define RST_STREAM 0x01 +#define CONNECTION_CLOSE 0x02 +#define GOAWAY 0x03 +#define WINDOW_UPDATE 0x04 +#define BLOCKED 0x05 +#define STOP_WAITING 0x06 +#define PING 0x07 + + +#define STREAM_ID_1BYTE 0x00 +#define STREAM_ID_2BYTE 0x01 +#define STREAM_ID_3BYTE 0x02 +#define STREAM_ID_4BYTE 0x03 + + +enum frame_type_t{ + FRAME_UNKNOWN = 0, + FRAME_STREAM, + FRAME_ACK, + FRAME_CONGESTION_FEEDBACK, + FRAME_PADDING, + FRAME_RST_STREAM, + FRAME_CONNECTION_CLOSE, + FRAME_GOAWAY, + FRAME_WINDOW_UPDATE, + FRAME_BLOCKED, + FRAME_STOP_WAITING, + FRAME_PING +}; + +/**************************************************************************/ +/* Message tag */ +/**************************************************************************/ +#define CHLO 0x43484C4F +#define SHLO 0x53484C4F +#define REJ 0x52454A00 +#define PRST 0x50525354 + +enum message_tag_t{ + MTAG_UNKNOWN = 0, + MTAG_CHLO, + MTAG_SHLO, + MTAG_REJ, + MTAG_PRST +}; + +struct gquic_frame_hdr{ + enum frame_type_t frame_type; + UCHAR is_fin; + UCHAR data_len_byte; + UCHAR offset_len; + UCHAR stream_id_len; + UINT8 stream_id; + UINT16 data_len; + UCHAR padding_len; + enum message_tag_t tag; + UINT32 tag_num; +}; + +struct gquic_pkt_hdr{ + UINT64 connection_id; + int connection_id_len; + UINT8 nonce_flag; + UINT8 reset_flag; + UINT8 version_flag; + UINT32 packet_number_len; + UINT32 version; + UINT8 version_int8; + UINT32 packet_number; + UCHAR auth_hash[MSG_AUTH_HASH_LEN]; +// struct gquic_frame_hdr* frame_hdr; +}; + +/**************************************************************************/ +/* Tag */ +/**************************************************************************/ +#define TAG_PAD 0x50414400 +#define TAG_SNI 0x534E4900 +#define TAG_VER 0x56455200 +#define TAG_CCS 0x43435300 +#define TAG_UAID 0x55414944 +#define TAG_PDMD 0x50444d44 +#define TAG_STK 0x53544b00 +#define TAG_SNO 0x534E4F00 +#define TAG_PROF 0x50524F46 +#define TAG_SCFG 0x53434647 +#define TAG_RREJ 0x5252454A +#define TAG_CRT 0x435254FF +#define TAG_AEAD 0x41454144 +#define TAG_SCID 0x53434944 +#define TAG_PUBS 0x50554253 +#define TAG_KEXS 0x4B455853 +#define TAG_OBIT 0x4F424954 +#define TAG_EXPY 0x45585059 +#define TAG_NONC 0x4E4F4E43 +#define TAG_MSPC 0x4D535043 +#define TAG_TCID 0x54434944 +#define TAG_SRBF 0x53524246 +#define TAG_ICSL 0x4943534C +#define TAG_SCLS 0x53434C53 +#define TAG_COPT 0x434F5054 +#define TAG_CCRT 0x43435254 +#define TAG_IRTT 0x49525454 +#define TAG_CFCW 0x43464357 +#define TAG_SFCW 0x53464357 +#define TAG_CETV 0x43455456 +#define TAG_XLCT 0x584C4354 +#define TAG_NONP 0x4E4F4E50 +#define TAG_CSCT 0x43534354 +#define TAG_CTIM 0x4354494D +#define TAG_MIDS 0x4D494453 +#define TAG_FHOL 0x46484F4C +#define TAG_STTL 0x5354544C +#define TAG_SMHL 0x534D484C +#define TAG_TBKP 0x54424B50 + +/* Public Reset Tag */ +#define TAG_RNON 0x524E4F4E +#define TAG_RSEQ 0x52534551 +#define TAG_CADR 0x43414452 + + + +UINT8 gquic_process(struct streaminfo *pstream, struct quic_stream* a_quic_stream, + unsigned long long region_flag, int thread_seq, void* a_packet, char* quic_data, UINT32 quic_data_len); +//UCHAR is_handshake_pkt(struct quic_stream* a_quic_stream, struct gquic_pkt_hdr* gquic_hdr, char * quic_data, UINT32 quic_data_len, UINT32 offset); +//void gquic_proc_unencrypt(struct streaminfo *pstream, struct gquic_pkt_hdr* gquic_hdr, struct quic_stream* a_quic_stream, +// unsigned long long region_flag, int thread_seq, void* a_packet, char * quic_data, UINT32 quic_data_len, UINT32 g_pos_t); +//UINT8 gquic_proc_tag(struct streaminfo *pstream, struct gquic_pkt_hdr* gquic_hdr, struct quic_stream *a_quic_stream, UINT16 tag_num, UINT8 direction, +// unsigned long long region_flag, int thread_seq, void* a_packet, char * quic_data, UINT32 quic_data_len, UINT32 g_pos_t); +UINT32 read_offset_len(UINT8 frame_type); +UINT32 read_stream_len(UINT8 frame_type); +UINT32 read_largest_observed_len(UINT8 frame_type); +UINT32 read_missing_packet_len(UINT8 frame_type); + +UINT32 get_stream_id(char* g_data_t, UINT32 offset, UINT8 stream_id_len); +UINT32 get_pkn(char* g_data_t, UINT32 offset, UINT8 pkn_len); +UINT32 read_seq_num_len(UINT8 flags); +int read_conn_id_len(UINT8 flags); + + +#endif + diff --git a/src/quic_analysis.c b/src/quic_analysis.c new file mode 100644 index 0000000..d83c602 --- /dev/null +++ b/src/quic_analysis.c @@ -0,0 +1,432 @@ +/* + * quic_analysis.c + * + * Created on: 2019年4月2日 + * Author: root + */ +#include "gquic.h" +#include "quic_analysis.h" +#include "gquic_process.h" +#include +#include + + +struct quic_param_t g_quic_param; + + +int QUIC_INIT(void) +{ + memset(&g_quic_param,0,sizeof(struct quic_param_t)); + strcat(g_quic_param.quic_conf_filename, "./conf/quic/quic.conf"); + if(0!=readconf(g_quic_param.quic_conf_filename)){ + return -1; + } + return 0; +}/*QUICINIT*/ + +void QUIC_DESTROY(void) +{ + return ; +}/*QUICDESTROY*/ + +void QUIC_GETPLUGID(unsigned short plugid) +{ + g_quic_param.quic_plugid = plugid; +} + +void QUIC_PROT_FUNSTAT(unsigned long long protflag) +{ + if(0==protflag){ + return; + } + g_quic_param.quic_interested_region_flag = protflag; + return; +}/*PROT_FUNSTAT*/ + +unsigned long long quic_getRegionID(char *string, int str_len,const char g_string[MAX_REGION_NUM][REGION_NAME_LEN]) +{ + unsigned long long i=0; + for(i=0;iopstate) + { + case OP_STATE_PENDING: + return_val = quic_init_stream(pstream, pme, thread_seq); + if(return_val < 0){ +#ifdef PRINTF + printf("initQuicStream error\n"); +#endif + return APP_STATE_DROPME; + } + case OP_STATE_DATA: + return_val = quic_analyseStream(pstream, pme, thread_seq, a_pcaket); + if(return_val == QUIC_RETURN_DROPME){ + quic_release_stream(pstream, pme, thread_seq, a_pcaket); + *pme = NULL; + return APP_STATE_DROPME; + } + break; + + case OP_STATE_CLOSE: + a_quic_stream = (struct quic_stream *)*pme; + if(a_quic_stream!=NULL) + { + a_quic_stream->fin_flag = QUIC_TRUE; + } + return_val = quic_analyseStream(pstream, pme, thread_seq, a_pcaket); + if(a_quic_stream!=NULL) + { + quic_release_stream(pstream, pme, thread_seq, a_pcaket); + *pme = NULL; + } + return APP_STATE_DROPME; + } + return APP_STATE_GIVEME; +}/*QUICNIT*/ + + +void quic_init_clientHello(struct quic_client_hello* stClientHello, UINT32 tag_num, int thread_seq) +{ + if(stClientHello==NULL) return ; + + if(tag_num == 0){ + }else{ + (stClientHello->ext_tags) = (quic_tlv_t **)dictator_malloc(thread_seq,tag_num*sizeof(quic_tlv_t*)); + int i=0; + for(i=0;iext_tags[i] = (quic_tlv_t *)dictator_malloc(thread_seq, sizeof(quic_tlv_t) ); + memset(stClientHello->ext_tags[i], 0, sizeof(quic_tlv_t)); + stClientHello->ext_tags[i]->ptr_value = (char *)dictator_malloc(thread_seq, sizeof(char)*MAX_TAG_VALUE_LEN); + stClientHello->ext_tags[i]->length = 0; + stClientHello->ext_tags[i]->type = 0; + } + } + +// stClientHello->ext_tag_len = 0; + stClientHello->ext_tag_num = tag_num; + memset(stClientHello->server_name, 0, SERVER_NAME_LEN); + memset(stClientHello->user_agent, 0, SERVER_NAME_LEN); + return; +} + +//void quic_init_clientHello(struct quic_client_hello* stClientHello, UINT32 tag_num, int thread_seq) +//{ +// if(stClientHello==NULL) return ; +// stClientHello->session.ptr_value = NULL; +// stClientHello->session.length = 0; +// stClientHello->ciphersuits.ptr_value = NULL; +// stClientHello->ciphersuits.length = 0; +// stClientHello->com_method.ptr_value = NULL; +// stClientHello->com_method.length = 0; +// memset(&stClientHello->random, 0, RANDOM_LEN); +// (stClientHello->ext_tags) = (struct quic_tlv_t **)dictator_malloc(thread_seq,tag_num*sizeof(struct quic_tlv_t*)); +// +// int i=0; +// for(i=0;iext_tags[i] = (struct quic_tlv_t *)dictator_malloc(thread_seq, sizeof(struct quic_tlv_t) ); +// memset(stClientHello->ext_tags[i], 0, sizeof(struct quic_tlv_t)); +// stClientHello->ext_tags[i]->ptr_value = (char *)dictator_malloc(thread_seq, sizeof(char)*MAX_TAG_VALUE_LEN); +// stClientHello->ext_tags[i]->length = 0; +// stClientHello->ext_tags[i]->type = 0; +// } +// stClientHello->ext_tag_len = 0; +// stClientHello->ext_tag_num = tag_num; +// memset(&stClientHello->server_name, 0, sizeof(stClientHello->server_name)); +// memset(&stClientHello->user_agent, 0, sizeof(stClientHello->user_agent)); +// return; +//} + +void quic_init_serverHello(struct quic_server_hello* stServerHello, UINT32 tag_num, int thread_seq) +{ + if(stServerHello==NULL) return ; +// stServerHello->session.ptr_value = NULL; +// stServerHello->session.length = 0; +// memset(&stServerHello->random, 0, RANDOM_LEN); + if(tag_num == 0){ + }else{ + (stServerHello->ext_tags) = (struct quic_tlv_t **)dictator_malloc(thread_seq,tag_num*sizeof(struct quic_tlv_t*)); + int i=0; + for(i=0;iext_tags[i] = (struct quic_tlv_t *)dictator_malloc(thread_seq, sizeof(quic_tlv_t)*20); + stServerHello->ext_tags[i] = (struct quic_tlv_t *)dictator_malloc(thread_seq, sizeof(quic_tlv_t)); + memset(stServerHello->ext_tags[i], 0, sizeof(quic_tlv_t)); + stServerHello->ext_tags[i]->ptr_value = (char *)dictator_malloc(thread_seq, sizeof(char)*MAX_TAG_VALUE_LEN); + stServerHello->ext_tags[i]->length = 0; + stServerHello->ext_tags[i]->type = 0; + } + } + + stServerHello->ext_tag_num = tag_num; + return; +} + +int quic_init_stream(struct streaminfo *pstream, void **pme, int thread_seq){ + + struct quic_stream *a_quic_stream = (struct quic_stream *)*pme; + if(NULL != a_quic_stream) + return -1; + a_quic_stream = (struct quic_stream *)dictator_malloc(thread_seq, sizeof(struct quic_stream)); + memset(a_quic_stream,0,sizeof(struct quic_stream)); + if (NULL == a_quic_stream) + { + return -1; + } + a_quic_stream->output_region_flag = g_quic_param.quic_interested_region_flag; + a_quic_stream->output_region_mask = QUIC_INTEREST_KEY_MASK; +// a_quic_stream->type = UNKNOWN_QUIC_TYPE; +// a_quic_stream->handshake_type = UNKNOWN_HANDSHAKE_TYPE; + a_quic_stream->is_quic_stream = QUIC_FALSE; + a_quic_stream->version_cfm = QUIC_FALSE; + a_quic_stream->version = 0; + a_quic_stream->link_state = QUIC_FALSE; + a_quic_stream->fin_flag = QUIC_FALSE; +// a_quic_stream->p_output_buffer = (struct quic_tlv_t*)dictator_malloc(thread_seq, sizeof(struct quic_tlv_t)); +// a_quic_stream->p_output_buffer->length = 0; +// a_quic_stream->p_output_buffer->ptr_value = 0; + a_quic_stream->business = (struct quic_business_info *)dictator_malloc(thread_seq,sizeof(struct quic_business_info)); + a_quic_stream->business->param = NULL; + a_quic_stream->business->return_value = PROT_STATE_GIVEME; + + *pme = (void*)a_quic_stream; + return 0; +} + +void quic_release_clientHello(int thread_seq, struct quic_client_hello* st_client_hello) +{ + if(st_client_hello==NULL) return ; +// if(st_client_hello->random.ptr_value!=NULL) +// { +// dictator_free(thread_seq,st_client_hello->random.ptr_value); +// st_client_hello->random.ptr_value = NULL; +// } +// if(st_client_hello->session.ptr_value!=NULL) +// { +// dictator_free(thread_seq,st_client_hello->session.ptr_value); +// st_client_hello->session.ptr_value = NULL; +// } +// if(st_client_hello->ciphersuits.ptr_value!=NULL) +// { +// dictator_free(thread_seq,st_client_hello->ciphersuits.ptr_value); +// st_client_hello->ciphersuits.ptr_value = NULL; +// } +// if(st_client_hello->com_method.ptr_value!=NULL) +// { +// dictator_free(thread_seq,st_client_hello->com_method.ptr_value); +// st_client_hello->com_method.ptr_value = NULL; +// } + if(st_client_hello->ext_tags != NULL){ + quic_release_exts(thread_seq, st_client_hello->ext_tags, st_client_hello->ext_tag_num); + dictator_free(thread_seq, st_client_hello->ext_tags); + st_client_hello->ext_tags = NULL; + } + return; +} + + + +void quic_release_serverHello(int thread_seq,struct quic_server_hello* st_server_hello) +{ + if(st_server_hello==NULL) return ; +// if(st_server_hello->session.ptr_value!=NULL) +// { +// dictator_free(thread_seq,st_server_hello->session.ptr_value); +// st_server_hello->session.ptr_value = NULL; +// } + if(st_server_hello->ext_tags != NULL){ + quic_release_exts(thread_seq, st_server_hello->ext_tags, st_server_hello->ext_tag_num); + dictator_free(thread_seq, st_server_hello->ext_tags); + st_server_hello->ext_tags = NULL; + } + return ; +} + +void quic_release_exts(int thread_seq, quic_tlv_t** ext_tags, UINT16 ext_tag_num){ + if(ext_tags == NULL) return; + int i = 0; + for(i = 0; i < ext_tag_num; i++){ + if(ext_tags[i] != NULL){ + if(ext_tags[i]->ptr_value != NULL){ + dictator_free(thread_seq, ext_tags[i]->ptr_value); + ext_tags[i]->ptr_value = NULL; + } + dictator_free(thread_seq, ext_tags[i]); + ext_tags[i] = NULL; + } + } + +} + +void quic_release_stream(struct streaminfo *a_tcp, void** pme, int thread_seq,void *a_packet) +{ + struct quic_stream *a_quic_stream = (struct quic_stream *)*pme; + if(NULL == a_quic_stream) return; + a_quic_stream->fin_flag = QUIC_TRUE; +// if(NULL != a_quic_stream->p_output_buffer) +// { +// if(a_quic_stream->p_output_buffer->ptr_value!=NULL) +// { +// dictator_free(thread_seq,a_quic_stream->p_output_buffer->ptr_value); +// a_quic_stream->p_output_buffer->ptr_value = NULL; +// } +// dictator_free(thread_seq,a_quic_stream->p_output_buffer); +// a_quic_stream->p_output_buffer = NULL; +// } + if(NULL != a_quic_stream->business) + { + if(a_quic_stream->business->param !=NULL){ + dictator_free(thread_seq,a_quic_stream->business->param); + a_quic_stream->business->param = NULL; + } + dictator_free(thread_seq,a_quic_stream->business); + a_quic_stream->business = NULL; + } + if(NULL != a_quic_stream->cert_chain.ptr_value) + { + dictator_free(thread_seq,a_quic_stream->cert_chain.ptr_value); + a_quic_stream->cert_chain.ptr_value = NULL; + } + if(NULL != a_quic_stream->common_cert.ptr_value) + { + dictator_free(thread_seq,a_quic_stream->common_cert.ptr_value); + a_quic_stream->common_cert.ptr_value = NULL; + } + if(NULL != a_quic_stream->cached_cert.ptr_value) + { + dictator_free(thread_seq,a_quic_stream->cached_cert.ptr_value); + a_quic_stream->cached_cert.ptr_value = NULL; + } + quic_release_serverHello(thread_seq, &a_quic_stream->st_server_hello); + quic_release_clientHello(thread_seq, &a_quic_stream->st_client_hello); + + dictator_free(thread_seq,a_quic_stream); + a_quic_stream = NULL; + return; +} + + +UINT8 quic_analyseStream(struct streaminfo *pstream, void** pme, int thread_seq, void *a_packet){ + struct quic_stream* a_quic_stream = (struct quic_stream *)*pme; + if(a_quic_stream == NULL){ + return QUIC_RETURN_DROPME; + } + UINT8 return_val = QUIC_RETURN_NORM; + struct udpdetail *udp_detail = (struct udpdetail *) pstream->pdetail; + if(udp_detail->datalen <= 0){ + return QUIC_RETURN_NORM; + } + + char* g_data_t = (char *)udp_detail->pdata; + UINT32 g_len_t = udp_detail->datalen; + + if(!a_quic_stream->is_quic_stream){ + if(g_len_t <= GQUIC_HEADER_LEN){ + return QUIC_RETURN_DROPME; + } + if(g_len_t > GQUIC_HEADER_LEN){ + return_val = gquic_process(pstream, a_quic_stream, a_quic_stream->output_region_flag, thread_seq, a_packet, g_data_t, g_len_t); + } + }else if(a_quic_stream->is_quic_stream){ + if(g_len_t > GQUIC_HEADER_LEN){ + gquic_process(pstream, a_quic_stream, a_quic_stream->output_region_flag, thread_seq, a_packet, g_data_t, g_len_t); + } + return QUIC_RETURN_NORM; + } + return return_val; +} + + +int quic_getLinkState(struct quic_stream *a_quic_stream) +{ + UCHAR state = 0; + if(QUIC_FALSE==(a_quic_stream)->link_state) + { + if(QUIC_TRUE==(a_quic_stream)->fin_flag) + state = SESSION_STATE_CLOSE | SESSION_STATE_PENDING; + else + state = SESSION_STATE_PENDING; + } + else + { + if(QUIC_TRUE==(a_quic_stream)->fin_flag) + { + state = SESSION_STATE_CLOSE; + } + else + state = SESSION_STATE_DATA; + } + (a_quic_stream)->link_state = QUIC_TRUE; + return state; +} + +UCHAR quic_doWithInsterestedRegion(struct streaminfo *pstream) +{ + /*业务层没有注册兴趣域*/ + if(g_quic_param.quic_interested_region_flag < QUIC_KEY){ + return APP_STATE_DROPME; + } + return QUIC_RETURN_NORM; +}/*ssl_doWithInsterestedRegion*/ + + + + diff --git a/src/quic_analysis.h b/src/quic_analysis.h new file mode 100644 index 0000000..1649e8f --- /dev/null +++ b/src/quic_analysis.h @@ -0,0 +1,78 @@ +/* + * quic_analysis.h + * + * Created on: 2019年4月2日 + * Author: root + */ + +#ifndef SRC_QUIC_ANALYSIS_H_ +#define SRC_QUIC_ANALYSIS_H_ + +#include +#include "quic_util.h" + +#define QUIC_TRUE 0x01 +#define QUIC_FALSE 0x00 +#define QUIC_HALF_CLOSE 0x01 +#define QUIC_WHOLE_CLOSE 0x02 +#define QUIC_DATA 0x03 +#define QUIC_KEY 1 +#define CT_GNUC_SO_EXPORT __attribute__ ((visibility("default"))) //符号导出本so文件 +#define CT_GNUC_SO_LOCAL __attribute__ ((visibility("hidden"))) //符号隐藏于本so文件中 +#define QUIC_RETURN_NORM 0x60 +#define QUIC_RETURN_UNNORM 0x61 +#define QUIC_RETURN_RESET_BUFFER 0x62 +#define QUIC_RETURN_DROPME 0x63 +#define MAX_REGION_NUM 15 +#define REGION_NAME_LEN 32 +#define GQUIC_HEADER_LEN 1+8+1 +#define IQUIC_HEADER_LEN 1+8+1 +#define ENC_BIG_ENDIAN 0x00000000 +#define ENC_LITTLE_ENDIAN 0x80000000 + +#define DIR_C2S 0x01 +#define DIR_S2C 0x02 +#define DIR_DOUBLE 0x03 + +struct quic_param_t +{ + unsigned long long quic_interested_region_flag; + unsigned long long quic_region_cnt; + char quic_conf_filename[256]; + unsigned short quic_plugid; + char quic_conf_regionname[MAX_REGION_NUM][REGION_NAME_LEN]; +}; + +enum quic_mes_type{ + VER_NEGO = 0, //vertion negotiation packet + PUB_RST, //public reset packet + FRAME, //frame packet + FEC, //FEC packet + Initial, //iquic + Retey, //iquic + Handshake, //iquic + MSG_UNKNOWN = 255 +}; + +int QUIC_INIT(void); +char QUIC_ENTRY(struct streaminfo *pstream, void**pme, int thread_seq,void *a_pcaket); +void QUIC_DESTROY(void); +void QUIC_GETPLUGID(unsigned short plugid); +void QUIC_PROT_FUNSTAT(unsigned long long protflag); +long long QUIC_FLAG_CHANGE(char* flag_str); +unsigned long long quic_getRegionID(char *string, int str_len, +const char g_string[MAX_REGION_NUM][REGION_NAME_LEN]); +UINT8 quic_analyseStream(struct streaminfo *pstream, void** pme, int thread_seq,void *a_packet); +int quic_init_stream(struct streaminfo *pstream, void **pme, int thread_seq); +void quic_init_clientHello(struct quic_client_hello* stClientHello, UINT32 tag_num, int thread_seq); +void quic_init_serverHello(struct quic_server_hello* stServerHello, UINT32 tag_num, int thread_seq); +void quic_release_exts(int thread_seq, quic_tlv_t** ext_tags, UINT16 ext_tag_num); +void quic_release_clientHello(int thread_seq,struct quic_client_hello* stClientHello); +void quic_release_serverHello(int thread_seq,struct quic_server_hello* stServerHello); +void quic_release_stream(struct streaminfo *a_tcp, void** pme, int thread_seq,void *a_packet); +UINT8 quic_analyseStream(struct streaminfo *pstream, void** pme, int thread_seq,void *a_packet); +int quic_getLinkState(struct quic_stream *a_quic_stream); +UCHAR quic_doWithInsterestedRegion(struct streaminfo *pstream); + +#endif /* SRC_QUIC_ANALYSIS_H_ */ + diff --git a/src/quic_callback.c b/src/quic_callback.c new file mode 100644 index 0000000..aab49d9 --- /dev/null +++ b/src/quic_callback.c @@ -0,0 +1,106 @@ +/* + * quic_callback.c + * + * Created on: 2019年4月13日 + * Author: root + */ +#include "gquic.h" +#include "quic_analysis.h" +extern struct quic_param_t g_quic_param; + +UCHAR quic_callPlugins(struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + stSessionInfo session_info; + region_flag = (region_flag >> (*a_quic_stream)->output_region_mask) % 2; + if( QUIC_TRUE==region_flag || (*a_quic_stream)->fin_flag==QUIC_TRUE ) + { + if (PROT_STATE_DROPME != (*a_quic_stream)->business->return_value) + { + session_info.plugid = g_quic_param.quic_plugid; + session_info.prot_flag = (((unsigned long long)1)<<(*a_quic_stream)->output_region_mask); + session_info.session_state = quic_getLinkState(*a_quic_stream) ; + session_info.app_info = (void*)(*a_quic_stream); +// session_info.buf = (*a_quic_stream)->p_output_buffer->ptr_value; +// session_info.buflen = (*a_quic_stream)->p_output_buffer->length; + (*a_quic_stream)->business->return_value = PROT_PROCESS(&session_info, + &((*a_quic_stream)->business->param),thread_seq,pstream, a_packet); + } + } + return QUIC_RETURN_NORM; +} + +UCHAR quic_proc_interest_region(enum quic_interested_region region_mask,struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + UCHAR return_val = QUIC_RETURN_NORM; + (*a_quic_stream)->output_region_mask = region_mask; + return_val = quic_callPlugins(a_quic_stream, pstream, region_flag, thread_seq, a_packet); + (*a_quic_stream)->output_region_mask = QUIC_INTEREST_KEY_MASK; + return return_val; +} +/* +UCHAR quic_doWithVersion(struct quic_stream** a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + UCHAR return_val = QUIC_RETURN_NORM; + if(!(g_quic_param.quic_interested_region_flag & QUIC_VERSION)) return return_val; + + (*a_quic_stream)->output_region_mask = QUIC_VERSION_MASK; + (*a_quic_stream)->p_output_buffer->ptr_value = (void*)(*a_quic_stream)->version; + (*a_quic_stream)->p_output_buffer->length = 4; + return_val = quic_callPlugins(a_quic_stream, pstream, region_flag, thread_seq, a_packet); + (*a_quic_stream)->p_output_buffer->ptr_value = NULL; + (*a_quic_stream)->p_output_buffer->length = 0; + (*a_quic_stream)->output_region_mask = QUIC_INTEREST_KEY_MASK; + return return_val; +} + +UCHAR quic_doWithApplicationData(char *pc_quic_data, int data_len, struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + UCHAR return_val = QUIC_RETURN_NORM; + (*a_quic_stream)->output_region_mask = QUIC_APPLICATION_DATA_MASK; + (*a_quic_stream)->p_output_buffer->ptr_value = pc_quic_data; + (*a_quic_stream)->p_output_buffer->length = data_len; + return_val = quic_callPlugins(a_quic_stream, pstream, region_flag, thread_seq, a_packet); + (*a_quic_stream)->p_output_buffer->ptr_value = NULL; + (*a_quic_stream)->p_output_buffer->length = 0; + (*a_quic_stream)->output_region_mask = QUIC_INTEREST_KEY_MASK; + return return_val; +} + +UCHAR quic_doWithClientHello(struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + UCHAR return_val = QUIC_RETURN_NORM; + (*a_quic_stream)->output_region_mask = QUIC_CLIENT_HELLO_MASK; + return_val = quic_callPlugins(a_quic_stream, pstream, region_flag, thread_seq, a_packet); + (*a_quic_stream)->output_region_mask = QUIC_INTEREST_KEY_MASK; + return return_val; +} + +UCHAR quic_doWithServerHello(struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + UCHAR return_val = QUIC_RETURN_NORM; + (*a_quic_stream)->output_region_mask = QUIC_SERVER_HELLO_MASK; + return_val = quic_callPlugins(a_quic_stream, pstream, region_flag, thread_seq, a_packet); + (*a_quic_stream)->output_region_mask = QUIC_INTEREST_KEY_MASK; + return return_val; +} + +UCHAR quic_doWithCert(char *pc_quic_data, int data_len, enum quic_interested_region cert, struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet) +{ + UCHAR return_val = QUIC_RETURN_NORM; + (*a_quic_stream)->output_region_mask = cert; + (*a_quic_stream)->p_output_buffer->ptr_value = pc_quic_data; + (*a_quic_stream)->p_output_buffer->length = data_len; + return_val = quic_callPlugins(a_quic_stream, pstream, region_flag, thread_seq, a_packet); + (*a_quic_stream)->p_output_buffer->ptr_value = NULL; + (*a_quic_stream)->p_output_buffer->length = 0; + (*a_quic_stream)->output_region_mask = QUIC_INTEREST_KEY_MASK; + return return_val; +} +*/ diff --git a/src/quic_callback.h b/src/quic_callback.h new file mode 100644 index 0000000..af706de --- /dev/null +++ b/src/quic_callback.h @@ -0,0 +1,21 @@ +/* + * quic_callback.h + * + * Created on: 2019年4月13日 + * Author: root + */ + +#ifndef SRC_QUIC_CALLBACK_H_ +#define SRC_QUIC_CALLBACK_H_ +#include "gquic.h" +UCHAR quic_callPlugins(struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet); +UCHAR quic_proc_interest_region(enum quic_interested_region region_mask,struct quic_stream **a_quic_stream, struct streaminfo *pstream, + unsigned long long region_flag, int thread_seq, void *a_packet); + +//UCHAR quic_doWithVersion(struct quic_stream** a_quic_stream, struct streaminfo *pstream, +// unsigned long long region_flag, int thread_seq, void *a_packet); +//UCHAR quic_doWithApplicationData(char *pc_quic_data, int data_len, struct quic_stream **a_quic_stream, struct streaminfo *pstream, +// unsigned long long region_flag, int thread_seq, void *a_packet); + +#endif /* SRC_QUIC_CALLBACK_H_ */ diff --git a/src/quic_util.c b/src/quic_util.c new file mode 100644 index 0000000..6ea2cc3 --- /dev/null +++ b/src/quic_util.c @@ -0,0 +1,210 @@ +/* + * quic_util.c + * + * Created on: 2019年4月4日 + * Author: root + */ +#include "quic_analysis.h" +#include +extern struct quic_param_t g_quic_param; + + +int readconf(const char* filename) +{ + FILE *fp = NULL; + char buf[2048] = {0}; + int region_id = 0; + int temp = 0; + char region_name[REGION_NAME_LEN] = {0}; + + if(((fp = fopen(filename, "r"))!=NULL)) + { + while( fgets(buf, sizeof(buf), fp)) + { + temp = sscanf(buf, "%d\t%s", ®ion_id, region_name); + if ( 2 > temp ) + { +#ifdef PRINTF + printf( "quic.so : quic.conf %s read error\n", filename); +#endif + return -1; + } + if(region_id>MAX_REGION_NUM) + { +#ifdef PRINTF + printf( "quic.so : quic.conf %d bigger than MAX_REGION_NUM\n", region_id); +#endif + return -1; + } + strncpy(g_quic_param.quic_conf_regionname[region_id], region_name, strlen(region_name)); + g_quic_param.quic_region_cnt++; + memset(region_name, 0, sizeof(region_name)); + } + fclose(fp); + } + else + { +#ifdef PRINTF + printf( "quic.so : quic.conf %s open error\n", filename); +#endif + return -1; + } + return 0; +} + +bool a_readUInt64(UINT64* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset){ + return a_readBytes(buf, sizeof(*buf), quic_data, quic_data_len, offset); +} + +bool a_readUInt32(UINT32* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset){ + return a_readBytes(buf, sizeof(*buf), quic_data, quic_data_len, offset); +} + +bool a_readUInt8(UINT8* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset){ + return a_readBytes(buf, sizeof(*buf), quic_data, quic_data_len, offset); +} + +bool a_readUInt16(UINT16* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset){ + return a_readBytes(buf, sizeof(*buf), quic_data, quic_data_len, offset); +} + +bool a_readBytes(void* buf, UINT32 len, char * quic_data, UINT32 quic_data_len, UINT32* quic_offset) { + UINT32 offset = *quic_offset; + if (!a_canRead(len, quic_data_len, offset)) { + return false; + } + memcpy(buf, quic_data + offset, len); + offset += len; + *quic_offset = offset; + return true; +} + +bool a_canRead(size_t bytes, UINT32 g_len_t, UINT32 g_pos_t) { + if(g_pos_t >= g_len_t){ + return false; + } + return bytes <= (g_len_t - g_pos_t); +} + +UINT64 a_pletoh64(const void *p, UINT32 offset) +{ + return (UINT64)*((const UINT8 *)(p)+7+offset)<<56| + (UINT64)*((const UINT8 *)(p)+6+offset)<<48| + (UINT64)*((const UINT8 *)(p)+5+offset)<<40| + (UINT64)*((const UINT8 *)(p)+4+offset)<<32| + (UINT64)*((const UINT8 *)(p)+3+offset)<<24| + (UINT64)*((const UINT8 *)(p)+2+offset)<<16| + (UINT64)*((const UINT8 *)(p)+1+offset)<<8| + (UINT64)*((const UINT8 *)(p)+0+offset)<<0; +} +UINT64 a_pletoh48(const void *p, UINT32 offset) +{ + return (UINT64)*((const UINT8 *)(p)+5+offset)<<40| + (UINT64)*((const UINT8 *)(p)+4+offset)<<32| + (UINT64)*((const UINT8 *)(p)+3+offset)<<24| + (UINT64)*((const UINT8 *)(p)+2+offset)<<16| + (UINT64)*((const UINT8 *)(p)+1+offset)<<8| + (UINT64)*((const UINT8 *)(p)+0+offset)<<0; +} + +UINT32 a_pletoh32(const void *p, UINT32 offset) +{ + return (UINT32)*((const UINT8 *)(p)+3+offset)<<24| + (UINT32)*((const UINT8 *)(p)+2+offset)<<16| + (UINT32)*((const UINT8 *)(p)+1+offset)<<8| + (UINT32)*((const UINT8 *)(p)+0+offset)<<0; +} + +UINT32 a_pletoh24(const void *p, UINT32 offset) +{ + return (UINT32)*((const UINT8 *)(p)+2+offset)<<16| + (UINT32)*((const UINT8 *)(p)+1+offset)<<8| + (UINT32)*((const UINT8 *)(p)+0+offset)<<0; +} + +//UINT16 a_pletoh16(const void *p) +//{ +// UINT32 offset = g_pos_t; +// return (UINT16)*((const UINT8 *)(p)+0+offset)<<0| +// (UINT16)*((const UINT8 *)(p)+1+offset)<<8; +//} + +UINT16 a_pletoh16(const void *p, UINT32 offset){ + return (UINT16)*((const UINT8 *)(p)+0+offset)<<0| + (UINT16)*((const UINT8 *)(p)+1+offset)<<8; +} + +UINT16 a_pntoh16(const void *p, UINT32 offset) +{ + return (UINT16)*((const UINT8 *)(p)+1+offset)<<0| + (UINT16)*((const UINT8 *)(p)+0+offset)<<8; +} + + +UINT32 a_pntoh24(const void *p, UINT32 offset) +{ + return (UINT32)*((const UINT8 *)(p)+0+offset)<<16| + (UINT32)*((const UINT8 *)(p)+1+offset)<<8| + (UINT32)*((const UINT8 *)(p)+2+offset)<<0; +} + +UINT32 a_pntoh32(const void *p, UINT32 offset) +{ + return (UINT32)*((const UINT8 *)(p)+0+offset)<<24| + (UINT32)*((const UINT8 *)(p)+1+offset)<<16| + (UINT32)*((const UINT8 *)(p)+2+offset)<<8| + (UINT32)*((const UINT8 *)(p)+3+offset)<<0; +} + +UINT64 a_pntoh48(const void *p, UINT32 offset) +{ + return (UINT64)*((const UINT8 *)(p)+0+offset)<<40| + (UINT64)*((const UINT8 *)(p)+1+offset)<<32| + (UINT64)*((const UINT8 *)(p)+2+offset)<<24| + (UINT64)*((const UINT8 *)(p)+3+offset)<<16| + (UINT64)*((const UINT8 *)(p)+4+offset)<<8| + (UINT64)*((const UINT8 *)(p)+5+offset)<<0; +} + +UINT64 a_pntoh64(const void *p, UINT32 offset) +{ + return (UINT64)*((const UINT8 *)(p)+0+offset)<<56| + (UINT64)*((const UINT8 *)(p)+1+offset)<<48| + (UINT64)*((const UINT8 *)(p)+2+offset)<<40| + (UINT64)*((const UINT8 *)(p)+3+offset)<<32| + (UINT64)*((const UINT8 *)(p)+4+offset)<<24| + (UINT64)*((const UINT8 *)(p)+5+offset)<<16| + (UINT64)*((const UINT8 *)(p)+6+offset)<<8| + (UINT64)*((const UINT8 *)(p)+7+offset)<<0; +} + +void a_phton64(UINT8 *p, UINT64 v) { + p[0] = (UINT8)(v >> 56); + p[1] = (UINT8)(v >> 48); + p[2] = (UINT8)(v >> 40); + p[3] = (UINT8)(v >> 32); + p[4] = (UINT8)(v >> 24); + p[5] = (UINT8)(v >> 16); + p[6] = (UINT8)(v >> 8); + p[7] = (UINT8)(v >> 0); +} + +int get_remaining_len(UINT32 g_len_t, UINT32 offset){ + return g_len_t - offset; +} + +void a_ntoa( unsigned int in, char *buffer) +{ + unsigned char *bytes = (unsigned char *) ∈ + snprintf( buffer, 15, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] ); +} + +//char* a_ntoa( unsigned int in, char * str) +//{ +// +// char buffer[64]; +// unsigned char *bytes = (unsigned char *) ∈ +// printf("%s %d.%d.%d.%d\t", str, bytes[0], bytes[1], bytes[2], bytes[3] ); +// snprintf( buffer, sizeof (buffer), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] ); +// return buffer; +//} diff --git a/src/quic_util.h b/src/quic_util.h new file mode 100644 index 0000000..f5c77ad --- /dev/null +++ b/src/quic_util.h @@ -0,0 +1,40 @@ +/* + * quic_util.h + * + * Created on: 2019-4-4 + * Author: root + */ +#ifndef SRC_QUIC_UTIL_H_ +#define SRC_QUIC_UTIL_H_ + +#include +#include +#include + +#include "gquic.h" + + +int readconf(const char* filename); +bool a_readUInt64(UINT64* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset); +bool a_readUInt32(UINT32* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset); +bool a_readUInt8(UINT8* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset); +bool a_readUInt16(UINT16* buf, char* quic_data, UINT32 quic_data_len, UINT32* offset); +bool a_readBytes(void* buf, UINT32 len, char * quic_data, UINT32 quic_data_len, UINT32* quic_offset); +bool a_canRead(size_t bytes, UINT32 g_len_t, UINT32 g_pos_t); +UINT64 a_pletoh64(const void *p, UINT32 offset); +UINT64 a_pletoh48(const void *p, UINT32 offset); +UINT32 a_pletoh32(const void *p, UINT32 offset); +UINT32 a_pletoh24(const void *p, UINT32 offset); +UINT16 a_pletoh16(const void *p, UINT32 offset); +UINT16 a_pntoh16(const void *p, UINT32 offset); +UINT32 a_pntoh24(const void *p, UINT32 offset); +UINT32 a_pntoh32(const void *p, UINT32 offset); +UINT64 a_pntoh48(const void *p, UINT32 offset); +UINT64 a_pntoh64(const void *p, UINT32 offset); +void a_phton64(UINT8 *p, UINT64 v); +int get_remaining_len(UINT32 g_len_t, UINT32 offset); +void a_ntoa( unsigned int in, char *buffer); + + + +#endif /* SRC_QUIC_UTIL_H_ */ diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..124fb04 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,61 @@ +CC = gcc +CCC = g++ + +INCLUDES += -I/opt/MESA/include/ +LIB = -L./opt/MESA/lib/ -lpthread +CFLAGS = -g3 -Wall -fPIC +CFLAGS += $(INCLUDES) + +TARGET = dpkt_plug_gquic.so +INF = dpkt_plug_gquic.inf +INSTALL_TARGET=$(TARGET) +LIB_FILE = $(wildcard ../lib/*.a) +SOURCES = $(wildcard *.cpp) +OBJECTS = $(SOURCES:.cpp=.o) +DEPS = $(SOURCES:.cpp=.d) + +INF=dpkt_plug_gquic.inf +INSTALL_TARGET=dpkt_plug_gquic.so +# $(CONF) +INSTALL_DIR=/home/mesasoft/sapp/plug/business/dpkt_plug_gquic/ + +all:$(TARGET) +$(TARGET):$(OBJECTS) $(LIB_FILE) + $(CCC) -shared $(CFLAGS) $(OBJECTS) $(LIB) -o $@ + mkdir -p $(INSTALL_DIR) + cp -r $(INSTALL_TARGET) $(INF) $(INSTALL_DIR) -f +# cp $(TARGET) ../bin/ + +.c.o: +%.d:%.c + $(CCC) $< -MM $(INCLUDES) > $@ + +%.o:%.cpp + $(CCC) -c -o $@ $(CFLAGS) $< $(INCLUDES) + +-include $(DEPS) + +clean : + rm -f $(OBJECTS) $(DEPS) $(TARGET) + +PLUGIN_PATH=./plug/business +CONFLIST_NAME=conflist_business.inf +PLUGIN_DIR_NAME=dpkt_plug_gquic +PLUGIN_INF_NAME=dpkt_plug_gquic.inf +PAPP_PATH=/home/dk/gitFile/ceiec/sapp + +TARGET_DIR=$(PAPP_PATH)/$(PLUGIN_PATH)/$(PLUGIN_DIR_NAME)/ +INSERT_FILE=$(PAPP_PATH)/$(PLUGIN_PATH)/$(CONFLIST_NAME) +INSERT_CONTENT=$(PLUGIN_PATH)/$(PLUGIN_DIR_NAME)/$(PLUGIN_INF_NAME) +install: + mkdir -p $(TARGET_DIR) + cp -r ../bin/*.inf $(TARGET_DIR) + cp -r ../bin/*.so $(TARGET_DIR) + cp -r ../bin/*.conf $(TARGET_DIR) + @ret=`cat $(INSERT_FILE)|grep $(INSERT_CONTENT)|wc -l`;if [ $$ret -eq 0 ];then echo $(INSERT_CONTENT) >>$(INSERT_FILE);fi + +CONF_DIR=$(PAPP_PATH)/conf/ +conf: + mkdir -p $(CONF_DIR) + cp -r ../bin/quic $(CONF_DIR) + diff --git a/test/dpkt_plug_gquic.cpp b/test/dpkt_plug_gquic.cpp new file mode 100644 index 0000000..276f978 --- /dev/null +++ b/test/dpkt_plug_gquic.cpp @@ -0,0 +1,118 @@ + +#include "dpkt_plug_gquic.h" + +#include +#include +#include "gquic.h" + + +void a_ntoa( unsigned int in, char *buffer) +{ + unsigned char *bytes = (unsigned char *) ∈ + int i = snprintf( buffer, 15, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] ); +} + +int DPKT_GQUIC_INIT() +{ + int plugid = DK_PLUGID_GQUIC; + return plugid; +} + +void DPKT_GQUIC_DESTROY() +{ + return; +} + + +char DPKT_GQUIC_ENTRY(stSessionInfo* session_info, void **pme, int _thread_num, struct streaminfo *pstream, void *a_packet) +{ + int thread_num = pstream->threadnum; + + if(session_info->session_state & SESSION_STATE_CLOSE) + { + return PROT_STATE_GIVEME; + } + + if(session_info->app_info ==NULL) + { + return PROT_STATE_GIVEME; + } + + if(session_info->prot_flag == QUIC_CLIENT_HELLO){ + printf("DPKT_QUIC_ENTRY\tQUIC_CLIENT_HELLO\n"); + struct quic_stream *quic = (struct quic_stream*)session_info->app_info; + if(quic){ + struct quic_client_hello client_hello = quic->st_client_hello; + + printf("BUSINESS PLUG:QUIC_CLIENT_HELLO ext_tag_num=%d--------------------\n",client_hello.ext_tag_num); + if(quic->version){ + printf("BUSINESS PLUG:QUIC_CLIENT_HELLO version=%d--------------------\n",quic->version); + + } + if(client_hello.server_name){ + printf("BUSINESS PLUG:QUIC_CLIENT_HELLO server_name=%s--------------------\n",client_hello.server_name); + + } + if(client_hello.user_agent){ + printf("BUSINESS PLUG:QUIC_CLIENT_HELLO user_agent=%s--------------------\n",client_hello.user_agent); + } + } + } + + + int i = 0, j = 0; + if(session_info->prot_flag == QUIC_VERSION){ + printf("DPKT_QUIC_ENTRY\tQUIC_VERSION\n"); + struct quic_stream *quic = (struct quic_stream*)session_info->app_info; + if(quic){ + printf("version:%d\n",quic->version); + } + } + + if(session_info->prot_flag == QUIC_SERVER_HELLO){ + printf("DPKT_QUIC_ENTRY\tQUIC_SERVER_HELLO\n"); + struct quic_stream *quic = (struct quic_stream*)session_info->app_info; + struct quic_server_hello server_hello = quic->st_server_hello; + printf("BUSINESS PLUG:QUIC_SERVER_HELLO ext_tag_num=%d--------------------\n",server_hello.ext_tag_num); + } + + if(session_info->prot_flag == QUIC_CACHED_CERT){ + printf("DPKT_QUIC_ENTRY\tQUIC_CACHED_CERT\n"); + struct quic_stream *quic = (struct quic_stream*)session_info->app_info; + quic_tlv_t cached_cert = quic->cached_cert; + printf("--------------------BUSINESS PLUG:QUIC_CACHED_CERT cached_cert_length=%d--------------------\n",cached_cert.length); + for(i = 0; i < cached_cert.length; i++){ + printf("%02X",((unsigned char*)cached_cert.ptr_value)[i]); + } + printf("----------------------------------------\n"); + } + + if(session_info->prot_flag == QUIC_COMM_CERT){ + printf("DPKT_QUIC_ENTRY\tQUIC_COMM_CERT\n"); + struct quic_stream *quic = (struct quic_stream*)session_info->app_info; + quic_tlv_t comm_cert = quic->common_cert; + printf("--------------------BUSINESS PLUG:QUIC_COMM_CERT common_cert_length=%d--------------------\n",comm_cert.length); + for(i = 0; i < comm_cert.length; i++){ + printf("%02X",((unsigned char*)comm_cert.ptr_value)[i]); + } + printf("--------------------T--------------------\n"); + } + + if(session_info->prot_flag == QUIC_CERT_CHAIN){ + printf("DPKT_QUIC_ENTRY\tQUIC_CERT_CHAIN\n"); + struct quic_stream *quic = (struct quic_stream*)session_info->app_info; + quic_tlv_t cert_chain = quic->cert_chain; + printf("--------------------BUSINESS PLUG:QUIC_CERT_CHAIN cert_chain_length=%d--------------------\n",cert_chain.length); + for(i = 0; i < cert_chain.length; i++){ + printf("%02X",((unsigned char*)cert_chain.ptr_value)[i]); + } + printf("----------------------------------------\n"); + } + + + return PROT_STATE_GIVEME; + +} + + + diff --git a/test/dpkt_plug_gquic.h b/test/dpkt_plug_gquic.h new file mode 100644 index 0000000..867f143 --- /dev/null +++ b/test/dpkt_plug_gquic.h @@ -0,0 +1,25 @@ +/* + * dk_plug_quic.h + * + * Created on: + * Author: root + */ + +#ifndef SRC_DPKT_PLUG_QUIC_H_ +#define SRC_DPKT_PLUG_QUIC_H_ + +#include "stream.h" + +#define DK_PLUGID_GQUIC 1003 +#ifdef __cplusplus +extern "C" { +#endif + +int DPKT_GQUIC_INIT(); +void DPKT_GQUIC_DESTROY(); +char DPKT_GQUIC_ENTRY(stSessionInfo* session_info, void **pme, int _thread_num, struct streaminfo *pstream, void *a_packet); + +#ifdef __cplusplus + } +#endif +#endif /* SRC_DPKT_PLUG_QUIC_H_ */ diff --git a/test/dpkt_plug_gquic.inf b/test/dpkt_plug_gquic.inf new file mode 100644 index 0000000..cb2c2c4 --- /dev/null +++ b/test/dpkt_plug_gquic.inf @@ -0,0 +1,13 @@ +[PLUGINFO] +PLUGNAME=dpkt_plug_gquic +SO_PATH=./plug/business/dpkt_plug_gquic/dpkt_plug_gquic.so +INIT_FUNC=DPKT_GQUIC_INIT +DESTROY_FUNC=DPKT_GQUIC_DESTROY + +[QUIC] +#FUNC_FLAG=QUIC_CLIENT_HELLO,QUIC_SERVER_HELLO,QUIC_CACHED_CERT,QUIC_COMM_CERT,QUIC_CERT_CHAIN,QUIC_VERSION,QUIC_APPLICATION_DATA + +FUNC_FLAG=QUIC_CLIENT_HELLO +FUNC_NAME=DPKT_GQUIC_ENTRY + + diff --git a/test/gquic.h b/test/gquic.h new file mode 100644 index 0000000..bb50c77 --- /dev/null +++ b/test/gquic.h @@ -0,0 +1,99 @@ +/* + * quic.h + * + * Created on: 2019-4-4 + * Author: root + */ + +#ifndef SRC_GQUIC_H_ +#define SRC_GQUIC_H_ + + + +#include +#define MAX_EXTENSION_NUM 128 +#define MAX_TAG_VALUE_LEN 257 +#define SERVER_NAME_LEN 64 +//add in 20191207 +#define USER_AGENT_LEN 256 +#define RANDOM_LEN 32 +#define QUIC_VERSION_LEN 4 + + +#define QUIC_INTEREST_KEY (1<