summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliumengyan <[email protected]>2020-05-12 12:18:02 +0800
committerliumengyan <[email protected]>2020-05-12 12:18:02 +0800
commitc0ed0eb78f3e05bc1a30d314169ae296720196c6 (patch)
tree520e2149c83bacced4cb3a303aa73967d215e1f5
first add
-rw-r--r--.gitignore8
-rw-r--r--README.md3
-rw-r--r--src/Makefile55
-rw-r--r--src/gquic.h107
-rw-r--r--src/gquic_process.c1082
-rw-r--r--src/gquic_process.h218
-rw-r--r--src/quic_analysis.c432
-rw-r--r--src/quic_analysis.h78
-rw-r--r--src/quic_callback.c106
-rw-r--r--src/quic_callback.h21
-rw-r--r--src/quic_util.c210
-rw-r--r--src/quic_util.h40
-rw-r--r--test/Makefile61
-rw-r--r--test/dpkt_plug_gquic.cpp118
-rw-r--r--test/dpkt_plug_gquic.h25
-rw-r--r--test/dpkt_plug_gquic.inf13
-rw-r--r--test/gquic.h99
17 files changed, 2676 insertions, 0 deletions
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 <stream.h>
+#include <MESA/stream.h>
+#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<<QUIC_INTEREST_KEY_MASK)
+#define QUIC_CLIENT_HELLO (1<<QUIC_CLIENT_HELLO_MASK)
+#define QUIC_SERVER_HELLO (1<<QUIC_SERVER_HELLO_MASK)
+#define QUIC_CACHED_CERT (1<<QUIC_CACHED_CERT_MASK)
+#define QUIC_COMM_CERT (1<<QUIC_COMM_CERT_MASK)
+#define QUIC_CERT_CHAIN (1<<QUIC_CERT_CHAIN_MASK)
+#define QUIC_APPLICATION_DATA (1<<QUIC_APPLICATION_DATA_MASK)
+#define QUIC_VERSION (1<<QUIC_VERSION_MASK)
+
+
+enum quic_interested_region {
+ QUIC_INTEREST_KEY_MASK = 0,
+ QUIC_CLIENT_HELLO_MASK,
+ QUIC_SERVER_HELLO_MASK,
+ QUIC_CACHED_CERT_MASK,
+ QUIC_COMM_CERT_MASK,
+ QUIC_CERT_CHAIN_MASK,
+ QUIC_APPLICATION_DATA_MASK,
+ QUIC_VERSION_MASK
+};
+
+
+typedef struct quic_tlv{
+ unsigned int type;
+ unsigned int length;
+ void *ptr_value;
+}quic_tlv_t;
+
+struct quic_business_info
+{
+ void* param;
+ uint8_t return_value;
+};
+
+struct quic_client_hello {
+ int server_name_len;
+ char server_name[SERVER_NAME_LEN];
+ int user_agent_len;
+ char user_agent[USER_AGENT_LEN];
+ uint16_t ext_tag_num; //number of extensions or tags
+ quic_tlv_t** ext_tags; //extensions or tags
+};
+
+struct quic_server_hello {
+// char random[RANDOM_LEN];
+// struct quic_tlv_t session;
+// uint16_t ciphersuit;
+// uint8_t com_method; //compress method
+ uint16_t ext_tag_num; //number of extensions or tags
+ quic_tlv_t** ext_tags; //extensions or tags
+};
+
+
+struct quic_stream {
+ unsigned char link_state;
+ uint8_t version_cfm;
+ uint32_t version;
+ uint8_t fin_flag;
+// uint8_t is_0rtt;
+ uint8_t is_quic_stream;
+
+ uint64_t gquic_cID;
+
+// struct quic_tlv_t* p_output_buffer;
+ struct quic_client_hello st_client_hello;
+ struct quic_server_hello st_server_hello;
+ struct quic_tlv cert_chain; //only gquic
+ struct quic_tlv cached_cert; //only gquic
+ struct quic_tlv common_cert; //only gquic
+ struct quic_business_info* business;
+ enum quic_interested_region output_region_mask;
+ uint64_t output_region_flag;
+};
+
+struct st_quic_client_hello* quic_get_clienthello(void* app_info);
+struct st_quic_server_hello* quic_get_serverhello(void* app_info);
+uint32_t quic_get_version(void* app_info);
+struct quic_tlv_t* quic_get_cert_chain(void* app_info);
+struct quic_tlv_t* quic_get_cached_cert(void* app_info);
+struct quic_tlv_t* quic_get_common_cert(void* app_info);
+void* quic_get_application_data(void* app_info);
+
+
+#endif /* SRC_GQUIC_H_ */
diff --git a/src/gquic_process.c b/src/gquic_process.c
new file mode 100644
index 0000000..e406d41
--- /dev/null
+++ b/src/gquic_process.c
@@ -0,0 +1,1082 @@
+/*
+ * gquic_process.c
+ *
+ * Created on: 2019��4��2��
+ * Author: root
+ */
+#include "gquic_process.h"
+#include "quic_analysis.h"
+#include "quic_callback.h"
+#include <stdbool.h>
+#include <stdio.h>
+#include<assert.h>
+
+
+#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 <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#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 <stdio.h>
+#include <MESA/stream_inc/stream_base.h>
+
+
+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;i<g_quic_param.quic_region_cnt;i++)
+ {
+ if(0==strcasecmp(g_string[i], string))
+ {
+ return i;
+ }
+ }
+ return 0;
+}
+
+long long QUIC_FLAG_CHANGE(char* flag_str)
+{
+ if(flag_str==NULL) return -1;
+ long long protflag = 0;
+ long long region_id = 0;
+ char *start_token = flag_str;
+ char *end_token = flag_str;
+ char *end_pos = flag_str+strlen(flag_str);
+ char region_name[REGION_NAME_LEN] = {0};
+
+ while (end_token < end_pos)
+ {
+ end_token = (char*)memchr(start_token, ',', end_pos-start_token);
+ if(end_token!=NULL)
+ {
+ memcpy(region_name, start_token, end_token-start_token);
+ start_token = end_token+1;
+ end_token += 1;
+ }
+ else
+ {
+ memcpy(region_name, start_token, end_pos-start_token);
+ end_token = end_pos;
+ }
+ region_id = quic_getRegionID(region_name, strlen(region_name), g_quic_param.quic_conf_regionname);
+ if(-1==region_id)
+ {
+#ifdef PRINTF
+ printf( "quic.so : PROT_CHANGE %s read %s error\n", flag_str, region_name);
+#endif
+ return -1;
+ }
+ protflag |= ((long long)1)<<region_id;
+ memset(region_name, 0, REGION_NAME_LEN);
+ }
+ return protflag;
+}
+
+char QUIC_ENTRY(struct streaminfo *pstream, void**pme, int thread_seq, void *a_pcaket)
+{
+ uint8_t return_val=0;
+ switch(quic_doWithInsterestedRegion(pstream))
+ {
+ case APP_STATE_DROPME:
+ return APP_STATE_DROPME;
+ default:
+ break;
+ }
+ struct quic_stream* a_quic_stream = NULL;
+ switch(pstream->opstate)
+ {
+ 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;i<tag_num;i++)
+ {
+ stClientHello->ext_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;i<tag_num;i++)
+// {
+// stClientHello->ext_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;i<tag_num;i++)
+ {
+// stServerHello->ext_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 <stdint.h>
+#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<stdio.h>
+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", &region_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 *) &in;
+ 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 *) &in;
+// 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 <stddef.h>
+#include <dlfcn.h>
+#include <stdbool.h>
+
+#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 <stdio.h>
+#include <dlfcn.h>
+#include "gquic.h"
+
+
+void a_ntoa( unsigned int in, char *buffer)
+{
+ unsigned char *bytes = (unsigned char *) &in;
+ 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 <MESA/stream.h>
+#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<<QUIC_INTEREST_KEY_MASK)
+#define QUIC_CLIENT_HELLO (1<<QUIC_CLIENT_HELLO_MASK)
+#define QUIC_SERVER_HELLO (1<<QUIC_SERVER_HELLO_MASK)
+#define QUIC_CACHED_CERT (1<<QUIC_CACHED_CERT_MASK)
+#define QUIC_COMM_CERT (1<<QUIC_COMM_CERT_MASK)
+#define QUIC_CERT_CHAIN (1<<QUIC_CERT_CHAIN_MASK)
+#define QUIC_APPLICATION_DATA (1<<QUIC_APPLICATION_DATA_MASK)
+#define QUIC_VERSION (1<<QUIC_VERSION_MASK)
+
+
+enum quic_interested_region {
+ QUIC_INTEREST_KEY_MASK = 0,
+ QUIC_CLIENT_HELLO_MASK,
+ QUIC_SERVER_HELLO_MASK,
+ QUIC_CACHED_CERT_MASK,
+ QUIC_COMM_CERT_MASK,
+ QUIC_CERT_CHAIN_MASK,
+ QUIC_APPLICATION_DATA_MASK,
+ QUIC_VERSION_MASK
+};
+
+
+typedef struct quic_tlv{
+ unsigned int type;
+ unsigned int length;
+ void *ptr_value;
+}quic_tlv_t;
+
+struct quic_business_info
+{
+ void* param;
+ uint8_t return_value;
+};
+
+struct quic_client_hello {
+ int server_name_len;
+ char server_name[SERVER_NAME_LEN];
+ int user_agent_len;
+ char user_agent[USER_AGENT_LEN];
+ uint16_t ext_tag_num; //number of extensions or tags
+ quic_tlv_t** ext_tags; //extensions or tags
+};
+
+struct quic_server_hello {
+ /*include random,session,ciphersuit,compress_method...*/
+ uint16_t ext_tag_num; //number of extensions or tags
+ quic_tlv_t** ext_tags; //extensions or tags
+};
+
+
+struct quic_stream {
+ unsigned char link_state;
+ uint8_t version_cfm;
+ uint32_t version;
+ uint8_t fin_flag;
+ uint8_t is_quic_stream;
+ uint64_t gquic_cID;
+ struct quic_client_hello st_client_hello;
+ struct quic_server_hello st_server_hello;
+ struct quic_tlv cert_chain;
+ struct quic_tlv cached_cert;
+ struct quic_tlv common_cert;
+ struct quic_business_info* business;
+ enum quic_interested_region output_region_mask;
+ uint64_t output_region_flag;
+};
+
+//struct st_quic_client_hello* quic_get_clienthello(void* app_info);
+//struct st_quic_server_hello* quic_get_serverhello(void* app_info);
+//uint32_t quic_get_version(void* app_info);
+//quic_tlv_t* quic_get_cert_chain(void* app_info);
+//quic_tlv_t* quic_get_cached_cert(void* app_info);
+//quic_tlv_t* quic_get_common_cert(void* app_info);
+//void* quic_get_application_data(void* app_info);
+
+
+#endif /* SRC_GQUIC_H_ */