summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuxueli <[email protected]>2020-05-29 15:10:01 +0800
committerliuxueli <[email protected]>2020-05-29 15:10:01 +0800
commit0b50dd7bc26450f935628c72fc6cb614b3fb4dfd (patch)
treeeae59af794de955e954cb263e00b920cab21646e
parentf77fd01b24c7f1dcf3f2261c485639f8a0ce972e (diff)
代码重构
-rw-r--r--README.md6
-rw-r--r--src/gquic.h91
-rw-r--r--src/gquic_process.c1105
-rw-r--r--src/gquic_process.h293
-rw-r--r--src/quic_analysis.c119
-rw-r--r--src/quic_analysis.h39
-rw-r--r--src/quic_callback.c61
-rw-r--r--src/quic_callback.h7
-rw-r--r--src/quic_version.cpp17
9 files changed, 797 insertions, 941 deletions
diff --git a/README.md b/README.md
index 96ee241..d592b56 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
# gquic
gquic protocol parse plugin
+
+
+
+Chromium currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
+
+https://quiche.googlesource.com/quiche/+/refs/heads/master/quic/core/quic_versions.h \ No newline at end of file
diff --git a/src/gquic.h b/src/gquic.h
index 2349548..6cbcdf5 100644
--- a/src/gquic.h
+++ b/src/gquic.h
@@ -8,24 +8,6 @@
#ifndef SRC_GQUIC_H_
#define SRC_GQUIC_H_
-enum GQUIC_VERSION
-{
- GQUIC_UNKNOWN=0,
- GQUIC_OTHERS,
- GQUIC_Q046
-};
-
-
-#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)
@@ -47,50 +29,55 @@ enum quic_interested_region {
QUIC_VERSION_MASK
};
-
-typedef struct quic_tlv{
+typedef struct _quic_tlv
+{
unsigned int type;
unsigned int length;
- void *ptr_value;
+ void *value;
}quic_tlv_t;
-struct quic_business_info
+#define MAX_CONNECT_ID_LEN 18
+
+struct _quic_public_header
{
- void* param;
- uint8_t return_value;
+ unsigned char public_flags;
+ unsigned int quic_version;
+ unsigned int server_CID_len;
+ unsigned int client_CID_len;
+ unsigned long long packet_number;
+ unsigned char server_CID[MAX_CONNECT_ID_LEN]; ////use first 8 bytes if GQUIC version 1~43
+ unsigned char client_CID[MAX_CONNECT_ID_LEN]; // no used if GQUIC version 1~43
};
-
-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 _gquic_frame_header
+{
+ unsigned char frame_type;
+ unsigned char fin_state;
+ unsigned short data_len;
+ unsigned int stream_id;
+ unsigned long long offset;
};
-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 count;
+ unsigned char sni_idx;
+ unsigned char ua_idx;
+ unsigned char ver_idx;
+ unsigned int 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 _quic_info
+{
+ struct _quic_stream *rej;
+ struct _quic_stream *client_hello;
+ struct _quic_stream *server_hello;
+ struct _gquic_frame_header frame_hdr;
+ struct _quic_public_header quic_hdr;
};
+//buff_len minimun 32bytes
+int quic_version_int2string(unsigned int version, char *buff, int buff_len);
+
#endif /* SRC_GQUIC_H_ */
diff --git a/src/gquic_process.c b/src/gquic_process.c
index c91b264..3254cbd 100644
--- a/src/gquic_process.c
+++ b/src/gquic_process.c
@@ -1,299 +1,515 @@
/*
- * gquic_process.c
+ * quic_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>
+#include <assert.h>
+#include <stdbool.h>
+#include <MESA/stream.h>
#include <MESA/MESA_handle_logger.h>
+#include "gquic_process.h"
+#include "quic_analysis.h"
-#define C2S 0x01
-#define S2C 0x02
-#define GQUIC_HANDSHAKE_LEN 12+1+1+4+4
-#define DIVERSIFICATION_NONCE_LEN 32
-
-extern struct quic_param_t g_quic_param;
-
-enum gquic_type
+int quic_getLinkState(struct _quic_context *_context)
{
- GQUIC=1,
- UNKNOWN_QUIC_TYPE
-};
+ UCHAR state = 0;
+
+ if(0==_context->link_state)
+ {
+ state=SESSION_STATE_PENDING|SESSION_STATE_DATA;
+ }
+ else
+ {
+ state=SESSION_STATE_DATA;
+ }
+
+ return state;
+}
-enum gquic_handshake_type
+char quic_callPlugins(struct streaminfo *pstream, struct _quic_context *_context, void *buff, int buff_len, enum quic_interested_region region_mask, void *a_packet)
{
- QUIC_Crypto=1,
- UNKNOWN_HANDSHAKE_TYPE
-};
+ char state=PROT_STATE_GIVEME;
+ char app_state=APP_STATE_GIVEME;
+ stSessionInfo session_info={0};
+
+ session_info.plugid=g_quic_param.quic_plugid;
+ session_info.prot_flag=(((unsigned long long)1)<<region_mask);
+ session_info.session_state=quic_getLinkState(_context) ;
+ session_info.app_info=(void*)(&_context->quic_info);
+ session_info.buf=buff;
+ session_info.buflen=buff_len;
+
+ state=PROT_PROCESS(&session_info, &(_context->business_pme), pstream->threadnum, pstream, a_packet);
+ if(state&PROT_STATE_DROPPKT)
+ {
+ app_state=APP_STATE_DROPPKT;
+ }
-int get_quic_tlv(char *start_pos, quic_tlv_t *tlv, int len, int type, int thread_seq)
-{
- if(tlv->ptr_value==NULL && len>0)
+ if(state&PROT_STATE_DROPME)
{
- tlv->ptr_value=(char *)dictator_malloc(thread_seq, len);
- memset(tlv->ptr_value, 0, len);
- tlv->length=len;
- tlv->type=type;
- memcpy(tlv->ptr_value, start_pos, tlv->length);
+ if(app_state&APP_STATE_DROPPKT)
+ {
+ app_state|=APP_STATE_DROPME;
+ }
+ else
+ {
+ app_state=APP_STATE_DROPME;
+ }
+ }
+
+ if(state&PROT_STATE_GIVEME)
+ {
+ app_state=APP_STATE_GIVEME;
}
- return 0;
+ return app_state;
}
-UINT32 get_stream_id(struct streaminfo *pstream, char* quic_data, UINT8 frame_type, UINT32 *skip_len)
+
+unsigned long long get_variable_length(char *p, int offset, int v_len)
{
- UINT16 data_length=0;
- UINT32 stream_id=0;
- UINT8 stream_id_len=0;
- UINT8 len_data=0,len_stream=0, len_offset=0;
-
- len_stream = read_stream_len(frame_type);
- switch(len_stream)
+ switch(v_len)
{
- case 1:
- stream_id=quic_data[*skip_len];
+ case 1:
+ return (unsigned long long)(p[offset]);
break;
case 2:
- stream_id=a_pletoh16((void *)quic_data, *skip_len);
+ return (unsigned long long)ntohs(*(unsigned short *)((char *)p+offset));
break;
case 3:
- stream_id=a_pletoh24((void *)quic_data, *skip_len);
+ return (unsigned long long)*(p+0+offset)<<16|
+ (unsigned long long)*(p+1+offset)<<8|
+ (unsigned long long)*(p+2+offset)<<0;
+ break;
+ case 4:
+ return (unsigned long long)ntohl(*(unsigned int *)(p+offset));
+ break;
+ case 5:
+ return (unsigned long long)*((unsigned char *)(p)+0+offset)<<32|
+ (unsigned long long)*((unsigned char *)(p)+1+offset)<<24|
+ (unsigned long long)*((unsigned char *)(p)+2+offset)<<16|
+ (unsigned long long)*((unsigned char *)(p)+3+offset)<<8|
+ (unsigned long long)*((unsigned char *)(p)+4+offset)<<0;
+ break;
+ case 6:
+ return (unsigned long long)*((unsigned char *)(p)+0+offset)<<40|
+ (unsigned long long)*((unsigned char *)(p)+1+offset)<<32|
+ (unsigned long long)*((unsigned char *)(p)+2+offset)<<24|
+ (unsigned long long)*((unsigned char *)(p)+3+offset)<<16|
+ (unsigned long long)*((unsigned char *)(p)+4+offset)<<8|
+ (unsigned long long)*((unsigned char *)(p)+5+offset)<<0;
+ break;
+ case 7:
+ return (unsigned long long)*((unsigned char *)(p)+0+offset)<<56|
+ (unsigned long long)*((unsigned char *)(p)+1+offset)<<40|
+ (unsigned long long)*((unsigned char *)(p)+2+offset)<<32|
+ (unsigned long long)*((unsigned char *)(p)+3+offset)<<24|
+ (unsigned long long)*((unsigned char *)(p)+4+offset)<<16|
+ (unsigned long long)*((unsigned char *)(p)+5+offset)<<8;
+ (unsigned long long)*((unsigned char *)(p)+6+offset)<<0;
+ break;
+ case 8:
+ return (unsigned long long)*((unsigned char *)(p)+0+offset)<<56|
+ (unsigned long long)*((unsigned char *)(p)+1+offset)<<48|
+ (unsigned long long)*((unsigned char *)(p)+2+offset)<<40|
+ (unsigned long long)*((unsigned char *)(p)+3+offset)<<32|
+ (unsigned long long)*((unsigned char *)(p)+4+offset)<<24|
+ (unsigned long long)*((unsigned char *)(p)+5+offset)<<16|
+ (unsigned long long)*((unsigned char *)(p)+6+offset)<<8|
+ (unsigned long long)*((unsigned char *)(p)+7+offset)<<0;
break;
default:
- stream_id=a_pletoh32((void *)quic_data, *skip_len);
break;
}
+
+ return 0;
+}
+
+int get_quic_tlv(char *start_pos, quic_tlv_t *tlv, int len, int type, int thread_seq)
+{
+ if(tlv->value==NULL && len>0)
+ {
+ tlv->value=(char *)dictator_malloc(thread_seq, len+1);
+ memset(tlv->value, 0, len+1);
+ tlv->length=len;
+ tlv->type=type;
+ memcpy(tlv->value, start_pos, tlv->length);
+ }
+
+ return 0;
+}
+
+int get_stream_id(struct streaminfo *pstream, struct _quic_context* _context, char* payload, unsigned char frame_type, int *used_len)
+{
+ int stream_len=0,offset_len=0;
+
+ _context->quic_info.frame_hdr.frame_type=frame_type;
- *skip_len+=len_stream; // stream ID length
+ stream_len=(frame_type&GQUIC_SPECIAL_FRAME_STREAM_ID)+1;
+ _context->quic_info.frame_hdr.stream_id=(unsigned int)get_variable_length(payload, *used_len, stream_len);
+ *used_len+=stream_len; // stream ID length
- if(frame_type&STREAM_D)
+ if(frame_type&GQUIC_SPECIAL_FRAME_STREAM_DLEN)
{
- data_length=ntohs(a_pletoh16((void *)quic_data, *skip_len));
- *skip_len+=2; //data length
+ _context->quic_info.frame_hdr.data_len=ntohs(*(unsigned short *)(payload+*used_len));
+ *used_len+=2; //data length
}
- len_offset=read_offset_len(frame_type);
- *skip_len+=len_offset;
+ offset_len=(frame_type&GQUIC_SPECIAL_FRAME_STREAM_OFFSET) ? (frame_type&GQUIC_SPECIAL_FRAME_STREAM_ID)+1 : 0;
+ _context->quic_info.frame_hdr.offset=get_variable_length(payload, *used_len, offset_len);
+ *used_len+=offset_len;
MESA_handle_runtime_log(g_quic_param.logger,
RLOG_LV_DEBUG,
"QUIC_FRAME",
- "stream_id: %u data length: %u offset length: %u addr: %s",
- stream_id,
- data_length,
- len_offset,
+ "frame_type: 0X%02X stream_id: %u data length: %u offset length: %u addr: %s",
+ frame_type,
+ _context->quic_info.frame_hdr.stream_id,
+ _context->quic_info.frame_hdr.data_len,
+ offset_len,
printaddr(&pstream->addr, pstream->threadnum));
- return stream_id;
+ return _context->quic_info.frame_hdr.stream_id;
}
-UINT32 get_packet_number(char* g_data_t, UINT32 offset, UINT8 pkn_len)
+unsigned long long get_packet_number(char* data, int offset, char pkn_len)
{
switch(pkn_len)
{
case 1:
- return g_data_t[offset];
+ return (unsigned long long)data[offset];
break;
case 2:
- return ntohs(a_pletoh16((void *)g_data_t, offset));
+ return (unsigned long long)ntohs(*(unsigned short *)(data+offset));
break;
case 4:
- return a_pletoh32((void *)g_data_t, offset);
+ return (unsigned long long)ntohl(*(unsigned int *)(data+offset));
break;
- default:
- return a_pletoh48((void *)g_data_t, offset);
+ case 8:
+ return get_variable_length(data, offset, 8);;
break;
}
return 0;
}
-enum GQUIC_VERSION is_gquic_protocol(struct streaminfo *pstream, char *payload, uint32_t payload_len, uint8_t *pub_flags, uint32_t *version, uint32_t *skip_len)
+// GQUIC version from 0 to 43
+static enum _QUIC_VERSION parse_q0to43_header(struct streaminfo *pstream, struct _quic_context* _context, char *payload, int payload_len, int *used_len)
{
- uint32_t is_q064=0;
- uint64_t connection_id = 0;
- int connection_id_len = 0;
- enum GQUIC_VERSION quic_version=GQUIC_UNKNOWN;
+ int i=0,len=0;
+ char public_flags=0;
- if(a_canRead(5, payload_len, *skip_len))
+ struct _quic_public_header *gquic_hdr=&(_context->quic_info.quic_hdr);
+ if(gquic_hdr==NULL)
{
- *skip_len+=1;
- strncpy((char*)&is_q064, payload+(*skip_len), 4);
- if(ntohl(is_q064)==VER_Q046)
+ gquic_hdr=(struct _quic_public_header *)dictator_malloc(pstream->threadnum, sizeof(struct _quic_public_header));
+ memset(gquic_hdr, 0, sizeof(struct _quic_public_header));
+ }
+
+ public_flags=payload[*used_len];
+ *used_len+=1;
+
+ //For Public Reset and Version Negotiation Packets (sent by the server) which don't have a packet number
+ if(!public_flags&GQUIC_PUBLIC_FLAG_PKT_NUM)
+ {
+ if(public_flags&GQUIC_PUBLIC_FLAG_VERSION) //Public Reset Packet
{
- *skip_len += 2;
- *version=(payload[*skip_len]&0x0f)*10 + (payload[*skip_len+1]&0x0f);
- *skip_len += 2;
-
- MESA_handle_runtime_log(g_quic_param.logger,
- RLOG_LV_DEBUG,
- "QUIC_PUB_FLAGS",
- "version: Q0%u addr: %s",
- *version,
- printaddr(&pstream->addr, pstream->threadnum));
-
- return GQUIC_Q046;
+ return QUIC_VERSION_UNKNOWN;// todo
+ }
+ else // Version Negotiation Packet
+ {
+ return QUIC_VERSION_UNKNOWN;
}
-
- *skip_len-=1;
}
-
- *pub_flags=payload[*skip_len]; // public flags
- *skip_len+=1;
- if(*pub_flags>PACKET_PUBLIC_FLAGS_MAX)
+ gquic_hdr->public_flags=public_flags;
+
+ if(gquic_hdr->public_flags&GQUIC_PUBLIC_FLAG_CID)
{
- return quic_version;
+ *(unsigned long long *)gquic_hdr->server_CID=get_variable_length(payload, *used_len, sizeof(gquic_hdr->server_CID));
+ *used_len+=sizeof(unsigned long long); // CID length
}
- connection_id_len=read_conn_id_len(*pub_flags);
- connection_id=(connection_id_len==0) ? 0 : (a_pntoh64((void *)payload, *skip_len));
- *skip_len+=connection_id_len; // CID length
-
- if(payload[*skip_len]==PUBLIC_FLAG_VER_FST_BYTE && *pub_flags&PUBLIC_FLAG_VER)
+ if(gquic_hdr->public_flags&GQUIC_PUBLIC_FLAG_VERSION && ntohs(*(unsigned short *)(payload+*used_len))==0x5130)
{
- *skip_len += 2;
- *version=(payload[*skip_len]&0x0f)*10 + (payload[*skip_len+1]&0x0f);
- *skip_len += 2;
- quic_version=GQUIC_OTHERS;
+ gquic_hdr->quic_version=(unsigned int)ntohl(*(unsigned int *)(payload+*used_len));
+ *used_len+=sizeof(int); // skip version
}
-
- if(*pub_flags==PUBLIC_FLAG_NONCE)
+ else
{
- *skip_len+=32; //diversification nonce
+ return QUIC_VERSION_UNKNOWN;
}
-
- UINT8 pkt_seq_len=read_seq_num_len(*pub_flags);
- UINT32 pkt_seq=get_packet_number(payload, *skip_len, pkt_seq_len);
- *skip_len+=pkt_seq_len; // skip pkt_num
- if(*pub_flags&PUBLIC_FLAG_VER)
+ switch(gquic_hdr->public_flags&0x30) // packet number
{
- //message authentication hash
- *skip_len+=MSG_AUTH_HASH_LEN;
+ case 0x30: // 6 bytes
+ gquic_hdr->packet_number=get_variable_length(payload, *used_len, 6);
+ *used_len+=6;
+ break;
+ case 0x20: // 4 bytes
+ gquic_hdr->packet_number=(unsigned long long)ntohl(*(unsigned int *)(payload+*used_len));
+ *used_len+=4;
+ break;
+ case 0x10: // 2bytes
+ gquic_hdr->packet_number=(unsigned long long)ntohs(*(unsigned short *)(payload+*used_len));
+ *used_len+=2;
+ break;
+ default: // 1 byte
+ gquic_hdr->packet_number=payload[*used_len];
+ *used_len+=1;
+ break;
+ }
- if(*version>0 && *version<34)
+ if(gquic_hdr->public_flags==GQUIC_PUBLIC_FLAG_NONCE)
+ {
+ *used_len+=32; //diversification nonce
+ }
+
+ if(gquic_hdr->public_flags&GQUIC_PUBLIC_FLAG_VERSION)
+ {
+ // Version 11 reduced the length of null encryption authentication tag from 16 to 12 bytes
+ if(gquic_hdr->quic_version > GQUIC_VERSION_Q010)
+ {
+ *used_len+=12;
+ }
+ else
{
- *skip_len+=1; //private flags
+ *used_len+=16;
}
+
+ // Version 34 removed entropy bits from packets and ACK frames,
+ // removed private flag from packet header and changed the ACK format to specify ranges of packets acknowledged rather than missing ranges.
+ if(gquic_hdr->quic_version < GQUIC_VERSION_Q034)
+ {
+ *used_len+=1; //private flags
+ }
+ }
+
+ _context->is_quic==QUIC_TRUE;
+
+ MESA_handle_runtime_log(g_quic_param.logger,
+ RLOG_LV_DEBUG,
+ "QUIC_IDETIFY",
+ "pub_flags: 0X%02X conection ID:[ destination: %llu ] version: Q%03u packet number: %llu dir(1: C2S;2: S2C): %d addr: %s",
+ gquic_hdr->public_flags,
+ *(unsigned long long *)gquic_hdr->server_CID,
+ (((gquic_hdr->quic_version>>8)&0x0000000F)*10) + ((gquic_hdr->quic_version)&0x0000000F),
+ gquic_hdr->packet_number,
+ pstream->curdir,
+ printaddr(&pstream->addr, pstream->threadnum));
+
+ return (enum _QUIC_VERSION)gquic_hdr->quic_version;
+}
+
+enum _QUIC_VERSION parse_quic_header(struct streaminfo *pstream, struct _quic_context* _context, char *payload, int payload_len, int *used_len)
+{
+ int i=0,len=0;
+ char client_CID[MAX_CONNECT_ID_LEN*2]={0};
+ char server_CID[MAX_CONNECT_ID_LEN*2]={0};
+
+ struct _quic_public_header *long_hdr=&(_context->quic_info.quic_hdr);
+
+ long_hdr->public_flags=payload[*used_len];
+ *used_len+=1; //skip public flags
+
+ if(long_hdr->public_flags&0x80)
+ {
+ long_hdr->quic_version=(unsigned int)ntohl(*(unsigned int *)(payload+*used_len));
+ *used_len+=sizeof(int); // skip version
+
+ long_hdr->client_CID_len=(payload[*used_len]&0xF) ? (payload[*used_len]&0xF)+3 : 0;
+ long_hdr->server_CID_len=((payload[*used_len]>>4)&0xF) ? ((payload[*used_len]>>4)&0xF)+3 : 0;
+ *used_len+=sizeof(char); // both connection_id length
+
+ memcpy(long_hdr->server_CID, (void *)(payload+*used_len), long_hdr->server_CID_len);
+ *used_len+=long_hdr->server_CID_len; // Destination connection_id length
+ memcpy(long_hdr->client_CID, (void *)(payload+*used_len), long_hdr->client_CID_len);
+ *used_len+=long_hdr->client_CID_len; // source connection_id length
+ }
+ else
+ {
+ if(pstream->curdir==DIR_C2S)// short header only destination connection ID
+ {
+ *used_len+=long_hdr->server_CID_len; // every packet destination connection ID is same
+ }
}
+ len=(long_hdr->public_flags&0x03)+1;
+ long_hdr->packet_number=get_packet_number(payload, *used_len, len);
+ *used_len+=len;
+
+ *used_len+=12; //message authentication hash
+
+ _context->is_quic==QUIC_TRUE;
+
+ for(i=0,len=0;i<long_hdr->server_CID_len; i++)
+ {
+ len+=snprintf(server_CID+len, sizeof(server_CID)-len, "%02X", long_hdr->server_CID[i]);
+ }
+
+ for(i=0,len=0;i<long_hdr->client_CID_len; i++)
+ {
+ len+=snprintf(client_CID+len, sizeof(client_CID)-len, "%02X", long_hdr->client_CID[i]);
+ }
+
MESA_handle_runtime_log(g_quic_param.logger,
RLOG_LV_DEBUG,
"QUIC_IDETIFY",
- "pub_flags: 0X%02X connection_id: %llu version: Q%03u packet number: %u dir(1: C2S;2: S2C): %d addr: %s",
- *pub_flags,
- connection_id,
- *version,
- pkt_seq,
+ "pub_flags: 0X%02X conection ID:[ destination: %s source: %s ] version: Q%03u packet number: %llu dir(1: C2S;2: S2C): %d addr: %s",
+ long_hdr->public_flags,
+ server_CID,
+ client_CID,
+ (((long_hdr->quic_version>>8)&0x0000000F)*10) + ((long_hdr->quic_version)&0x0000000F),
+ long_hdr->packet_number,
pstream->curdir,
printaddr(&pstream->addr, pstream->threadnum));
+
+ return (enum _QUIC_VERSION)long_hdr->quic_version;
+}
+
+enum _QUIC_VERSION is_quic_protocol(struct streaminfo *pstream, struct _quic_context* _context, char *payload, int payload_len, int *used_len)
+{
+ int i=0,len=0;
+ size_t s_id_len=0,d_id_len=0;
+ char d_CID[128]={0}, s_CID[128]={0};
+ unsigned char s_connection_id[MAX_CONNECT_ID_LEN]={0};
+ unsigned char d_connection_id[MAX_CONNECT_ID_LEN]={0};
+ enum _QUIC_VERSION quic_version=QUIC_VERSION_UNKNOWN;
+
+ if(_context->quic_info.quic_hdr.quic_version!=QUIC_VERSION_UNKNOWN)
+ {
+ //
+ quic_version=(enum _QUIC_VERSION)(_context->quic_info.quic_hdr.quic_version);
+ }
+ else
+ {
+ // The most significant bit (0x80) of byte 0 (the first byte) is set to 1 for long headers
+ (payload[*used_len]&0x80) ? (quic_version=(enum _QUIC_VERSION)ntohl(*(unsigned int *)(payload+(*used_len+1)))) : QUIC_VERSION_UNKNOWN;
+ }
- return quic_version;
+ switch(quic_version) // +1 meaning: skip public flags
+ {
+ case GQUIC_VERSION_Q046:
+ quic_version=parse_quic_header(pstream, _context, payload, payload_len, used_len);
+ return quic_version;
+ break;
+ //case IETF: unsupport
+ break;
+ default:
+ break;
+ }
+
+ // Q001~Q043: 0x80 is currently unused, and must be set to 0
+ if(payload[*used_len]>0x80)
+ {
+ return QUIC_VERSION_UNKNOWN;
+ }
+
+ return parse_q0to43_header(pstream, _context, payload, payload_len, used_len);
}
-void gquic_proc_tag(struct streaminfo *pstream, struct quic_stream *a_quic_stream, UINT16 tag_num, UINT8 direction, void* a_packet, char * quic_data, UINT32 quic_data_len, UINT32 *used_len)
+int parse_extension_tag(struct streaminfo *pstream, struct _quic_stream **quic_stream, void *a_packet, char *payload, int payload_len, int *used_len, int tag_num)
{
- UCHAR return_val;
- UINT32 tag_type;
- UINT32 total_tag_len=0, tag_len=0;
- UINT32 tag_value_start=tag_num*4*2+(*used_len); // skip length of type and offset, type(offset)=szieof(int)
- UINT32 tag_offset_end=0, pre_tag_offset_end=0;
- int tag_type_len=4, tag_offset_len=4,num=0;
- enum quic_interested_region region_mask=QUIC_INTEREST_KEY_MASK;
-
- while(tag_num > 0 && a_canRead(tag_type_len+tag_offset_len, quic_data_len, *used_len))
- {
- tag_type=a_pntoh32(quic_data, *used_len);
- *used_len+=4;
+ int ret=0,tag_used_num=0;
+ int tag_type,skip_tsg=0;
+ int total_tag_len=0,tag_len=0;
+ int tag_offset_end=0,pre_tag_offset_end=0;
+
+ struct _quic_stream *stream=*quic_stream;
+ int tag_value_start=tag_num*4*2+(*used_len); // skip length of type and offset, type(offset)=szieof(int)
+
+ if(stream==NULL)
+ {
+ stream=(struct _quic_stream *)dictator_malloc(pstream->threadnum, sizeof(struct _quic_stream));
+ memset(stream, 0, sizeof(struct _quic_stream));
+ stream->ext_tags=(quic_tlv_t *)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t));
+ memset(stream->ext_tags, 0, tag_num*sizeof(quic_tlv_t));
+ *quic_stream=stream;
+ }
+ else
+ {
+ quic_release_exts(pstream->threadnum, stream->ext_tags, stream->ext_tag_num);
+ stream->ext_tags=(quic_tlv_t *)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t));
+ memset(stream->ext_tags, 0, tag_num*sizeof(quic_tlv_t));
+ *quic_stream=stream;
+ stream->ext_tag_num=0;
+ stream->count++;
+ }
+
+ while(tag_num>tag_used_num)
+ {
+ tag_type=ntohl(*(unsigned int *)(payload+*used_len));
+ *used_len+=sizeof(int);
- tag_offset_end=a_pletoh32(quic_data, *used_len);
- *used_len+=4;
+ tag_offset_end=*(unsigned int *)(payload+*used_len);
+ *used_len+=sizeof(int);
tag_len=tag_offset_end-pre_tag_offset_end;
- if(tag_len<0 || (tag_offset_end>=quic_data_len) || (tag_len>quic_data_len-tag_value_start))
+ if(tag_len<0 || (tag_offset_end>=payload_len) || (tag_len>payload_len-tag_value_start))
{
- return ;
+ return -1;
}
switch(tag_type)
{
case TAG_PAD:
break;
- case TAG_CCS: //common_cert
- region_mask=QUIC_COMM_CERT_MASK;
- get_quic_tlv(quic_data+tag_value_start, &a_quic_stream->common_cert, tag_len, tag_type, pstream->threadnum);
- break;
- case TAG_CCRT: //cached_cert
- region_mask=QUIC_CACHED_CERT_MASK;
- get_quic_tlv(quic_data+tag_value_start, &a_quic_stream->cached_cert, tag_len, tag_type, pstream->threadnum);
+ case TAG_VER:
+ stream->ver_idx=stream->ext_tag_num;
+ get_quic_tlv(payload+tag_value_start, &stream->ext_tags[stream->ext_tag_num], tag_len, tag_type, pstream->threadnum);
+ *(unsigned int *)(stream->ext_tags[stream->ext_tag_num].value)=(unsigned int)ntohl(*(unsigned int *)(stream->ext_tags[stream->ext_tag_num].value));
+ MESA_handle_runtime_log(g_quic_param.logger,
+ RLOG_LV_DEBUG,
+ "QUIC_VERSION",
+ "Quic version: 0X%X addr: %s",
+ *(unsigned int *)(stream->ext_tags[stream->ext_tag_num].value),
+ printaddr(&pstream->addr, pstream->threadnum));
break;
- case TAG_CRT: //cert_chain ????? length need change
- if(a_quic_stream->cert_chain.length==0)
- {
- //tag_value_start += a_quic_stream->cert_chain.length;
- tag_len=(tag_len>(quic_data_len-tag_value_start+1) ? (quic_data_len-tag_value_start+1) : tag_len);
- get_quic_tlv(quic_data+tag_value_start, &a_quic_stream->cached_cert, tag_len, tag_type, pstream->threadnum);
- region_mask=QUIC_CERT_CHAIN_MASK;
- }
+ case TAG_UAID:
+ stream->ua_idx=stream->ext_tag_num;
+ get_quic_tlv(payload+tag_value_start, &stream->ext_tags[stream->ext_tag_num], tag_len, tag_type, pstream->threadnum);
+ MESA_handle_runtime_log(g_quic_param.logger,
+ RLOG_LV_DEBUG,
+ "QUIC_UA",
+ "User Agent: %s addr: %s",
+ stream->ext_tags[stream->ext_tag_num].value,
+ printaddr(&pstream->addr, pstream->threadnum));
+ stream->ext_tag_num++;
break;
case TAG_SNI:
- if(a_quic_stream->st_client_hello.server_name_len==0)
- {
- a_quic_stream->st_client_hello.server_name_len=(tag_len>SERVER_NAME_LEN ? SERVER_NAME_LEN : tag_len);
- memcpy(a_quic_stream->st_client_hello.server_name, quic_data + tag_value_start, tag_len);
- MESA_handle_runtime_log(g_quic_param.logger,
+ stream->sni_idx=stream->ext_tag_num;
+ get_quic_tlv(payload+tag_value_start, &stream->ext_tags[stream->ext_tag_num], tag_len, tag_type, pstream->threadnum);
+ MESA_handle_runtime_log(g_quic_param.logger,
RLOG_LV_DEBUG,
"QUIC_SNI",
"SNI: %s addr: %s",
- a_quic_stream->st_client_hello.server_name,
+ stream->ext_tags[stream->ext_tag_num].value,
printaddr(&pstream->addr, pstream->threadnum));
-
- }
- break;
- case TAG_UAID:
- 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);
- memcpy(a_quic_stream->st_client_hello.user_agent, quic_data + tag_value_start, a_quic_stream->st_client_hello.user_agent_len);
- }
+ stream->ext_tag_num++;
break;
default:
- if(direction == 0x01 && num < a_quic_stream->st_client_hello.ext_tag_num)
- {
- a_quic_stream->st_client_hello.ext_tags[num]=(quic_tlv_t *)dictator_malloc(pstream->threadnum, sizeof(quic_tlv_t));
- get_quic_tlv(quic_data+tag_value_start, a_quic_stream->st_client_hello.ext_tags[num], (tag_len>MAX_TAG_VALUE_LEN-1 ? MAX_TAG_VALUE_LEN-1 : tag_len), tag_type, pstream->threadnum);
- }
- else if(num < a_quic_stream->st_server_hello.ext_tag_num)
- {
- a_quic_stream->st_server_hello.ext_tags[num]=(quic_tlv_t *)dictator_malloc(pstream->threadnum, sizeof(quic_tlv_t));
- get_quic_tlv(quic_data+tag_value_start, a_quic_stream->st_server_hello.ext_tags[num], (tag_len>MAX_TAG_VALUE_LEN-1 ? MAX_TAG_VALUE_LEN-1 : tag_len), tag_type, pstream->threadnum);
- }
- num++;
+ get_quic_tlv(payload+tag_value_start, &stream->ext_tags[stream->ext_tag_num], tag_len, tag_type, pstream->threadnum);
+ stream->ext_tag_num++;
break;
}
- tag_num--;
+ tag_used_num++;
tag_value_start+=tag_len;
total_tag_len+=tag_len;
pre_tag_offset_end=tag_offset_end;
-
- return_val=quic_callPlugins(a_quic_stream, pstream, region_mask, pstream->threadnum, a_packet);
- region_mask=QUIC_INTEREST_KEY_MASK;
}
*used_len += total_tag_len;
- return;
+ return ret;
}
+#if 0
int gquic_frame_type_ack(struct quic_stream* a_quic_stream, char * quic_data, UINT32 quic_data_len, UINT8 frame_type, UINT32 *used_len)
{
UINT8 num_timestamp, num_ranges, num_revived, num_blocks;
@@ -369,7 +585,7 @@ int gquic_frame_type_ack(struct quic_stream* a_quic_stream, char * quic_data, UI
// return value: Have no meaning, only numerical value
int gquic_frame_type_control(struct quic_stream* a_quic_stream, char * quic_data, UINT32 quic_data_len, UINT8 frame_type, uint32_t pkt_num_len, UINT32 *used_len)
{
- UINT16 len_reason;
+ int len_reason;
*used_len+=1;
switch(frame_type)
@@ -425,476 +641,183 @@ int gquic_frame_type_control(struct quic_stream* a_quic_stream, char * quic_data
return QUIC_TRUE;
}
+#endif
-int gquic_frame_type_stream(struct streaminfo *pstream, struct quic_stream* a_quic_stream, char *quic_data, UINT32 quic_data_len, UINT8 frame_type, UINT32 *used_len, void* a_packet)
+int gquic_frame_type_stream(struct streaminfo *pstream, struct _quic_context* _context, char *payload, int payload_len, int *used_len, char frame_type, void *a_packet)
{
- UINT8 return_val;
- UINT16 tag_num = 0;
- UINT32 stream_id, message_tag;
- if(frame_type&STREAM_F)
- {
- a_quic_stream->fin_flag=QUIC_TRUE;
- }
-
- stream_id=get_stream_id(pstream, quic_data, frame_type, used_len);
-
- if(stream_id==1) //handshake
- {
- message_tag = a_pntoh32((void *)quic_data, *used_len);
- *used_len += 4;
- tag_num = a_pletoh16(quic_data, *used_len);
- *used_len += 2; //tag_num
- *used_len += 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.ext_tags=(quic_tlv_t **)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t*));
- a_quic_stream->st_client_hello.ext_tag_num = tag_num;
- }
- else
- {
- if(a_quic_stream->st_server_hello.ext_tag_num && tag_num>a_quic_stream->st_client_hello.ext_tag_num)
- {
- quic_release_exts(pstream->threadnum, a_quic_stream->st_client_hello.ext_tags, a_quic_stream->st_client_hello.ext_tag_num);
- a_quic_stream->st_client_hello.ext_tags=(quic_tlv_t **)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t*));
- a_quic_stream->st_client_hello.ext_tag_num = tag_num;
- }
- else
- {
- return -1;
- }
- }
- gquic_proc_tag(pstream, a_quic_stream, tag_num, C2S, a_packet, quic_data, quic_data_len, used_len);
- if(a_quic_stream->st_client_hello.server_name_len>0 || a_quic_stream->st_client_hello.user_agent_len>0)
- {
- quic_callPlugins(a_quic_stream, pstream, QUIC_CLIENT_HELLO_MASK, pstream->threadnum, a_packet);
- }
- break;
- case SHLO: //MTAG_SHLO;
- if(a_quic_stream->st_server_hello.ext_tags==NULL)
- {
- return -2;
- }
-
- a_quic_stream->st_server_hello.ext_tags=(quic_tlv_t **)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t*));
- a_quic_stream->st_server_hello.ext_tag_num=tag_num;
-
- gquic_proc_tag(pstream, a_quic_stream, tag_num, S2C, a_packet, quic_data, quic_data_len, used_len);
+ int ret=0;
+ unsigned short tag_num = 0;
+ unsigned int stream_id, message_tag;
- if(a_quic_stream->st_server_hello.ext_tags != NULL)
- {
- quic_callPlugins(a_quic_stream, pstream, QUIC_SERVER_HELLO_MASK, pstream->threadnum, a_packet);
- }
- break;
- case REJ: //MTAG_REJ;
- if(a_quic_stream->st_server_hello.ext_tags!=NULL)
- {
- return -3;
-
- }
-
- a_quic_stream->st_server_hello.ext_tags=(quic_tlv_t **)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t*));
- a_quic_stream->st_server_hello.ext_tag_num=tag_num;
-
- gquic_proc_tag(pstream, a_quic_stream, tag_num, S2C, a_packet, quic_data, quic_data_len, used_len);
- if(a_quic_stream->st_server_hello.ext_tags != NULL)
- {
- quic_callPlugins(a_quic_stream, pstream, QUIC_SERVER_HELLO_MASK, pstream->threadnum, a_packet);
- }
- break;
- default:
- break;
- }
- }
+ stream_id=get_stream_id(pstream, _context, payload, frame_type, used_len);
- return 0;
-}
+ message_tag=(unsigned int)ntohl(*(unsigned int *)(payload+*used_len));
+ *used_len+=4;
-//frame type->stream->offset->data length
-void gquic_proc_unencrypt(struct streaminfo *pstream, struct quic_stream* a_quic_stream, uint32_t pkt_num_len, void* a_packet, char * quic_data, UINT32 quic_data_len, UINT32 *used_len)
-{
- UINT8 frame_type;
- UINT32 ret=0;
+ tag_num=*(unsigned short *)(payload+*used_len);
+ *used_len+=2; //tag_num
+ *used_len+=2; //padding
- while(*used_len<quic_data_len)
+ switch(message_tag)
{
- a_readUInt8(&frame_type, quic_data, quic_data_len, used_len);
-
- if(!(frame_type&FRAM_SPECIAL))
- {
- ret=gquic_frame_type_control(a_quic_stream, quic_data, quic_data_len, frame_type, pkt_num_len, used_len);
- }
- else
- {
- //special packet
- if(frame_type&STREAM)
+ case CHLO: //MTAG_CHLO;
+ ret=parse_extension_tag(pstream, &_context->quic_info.client_hello, a_packet, payload, payload_len, used_len, tag_num);
+ if(ret>=0)
{
- ret=gquic_frame_type_stream(pstream, a_quic_stream, quic_data, quic_data_len, frame_type, used_len, a_packet);
+ ret=quic_callPlugins(pstream, _context, (void *)(_context->quic_info.client_hello), sizeof(void *), QUIC_CLIENT_HELLO_MASK, a_packet);
}
- else if(frame_type&ACK)
+ break;
+ case SHLO: //MTAG_SHLO;
+ ret=parse_extension_tag(pstream, &_context->quic_info.server_hello, a_packet, payload, payload_len, used_len, tag_num);
+ if(ret>=0)
{
- gquic_frame_type_ack(a_quic_stream, quic_data, quic_data_len, frame_type, used_len);
+ ret=quic_callPlugins(pstream, _context, (void *)(_context->quic_info.server_hello), sizeof(void *), QUIC_SERVER_HELLO_MASK, a_packet);
}
- else
+ break;
+ case REJ: //MTAG_REJ;
+ ret=parse_extension_tag(pstream, &_context->quic_info.rej, a_packet, payload, payload_len, used_len, tag_num);
+ if(ret>=0)
{
- *used_len+=1;
- ret=QUIC_FALSE;
+ ret=quic_callPlugins(pstream, _context, (void *)(_context->quic_info.rej), sizeof(void *), QUIC_SERVER_HELLO_MASK, a_packet);
}
- }
-
- if(ret!=QUIC_TRUE)
- {
- return ;
- }
+ break;
+ default:
+ break;
}
- return;
-}
+ return (ret>=0) ? ret : APP_STATE_GIVEME;
+}
-//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 *used_len)
+//frame type->stream->offset->data length
+int gquic_proc_unencrypt(struct streaminfo *pstream, struct _quic_context* _context, void *a_packet, char * payload, int payload_len, int *used_len)
{
- int ret=0;
- UINT8 frame_type=0;
- UINT32 message_tag;
-
- while(*used_len < quic_data_len)
- {
- frame_type = quic_data[*used_len];
-
- if(!(frame_type & FRAM_SPECIAL))
- {
- ret=gquic_frame_type_control(a_quic_stream, quic_data, quic_data_len, frame_type, pkt_num_len, used_len);
- a_quic_stream->fin_flag=QUIC_FALSE; // is_handshake_pkt don't identify QUIC; but function set QUIC_TRUE
- if(ret!=QUIC_TRUE)
- {
- return ret;
- }
- }
- else
+ unsigned int ret=0;
+ unsigned char frame_type;
+
+ while(*used_len<payload_len)
+ {
+ frame_type=payload[*used_len];
+ *used_len+=1; //skip frame_type
+
+ switch(frame_type)
{
- if(frame_type&STREAM)
- {
- if(frame_type&STREAM_D)
+ case GQUIC_REGULAR_FRAME_PADDING:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_RST_STREAM:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_CONNECTION_CLOSE:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_GOAWAY:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_WINDOW_UPDATE:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_BLOCKED:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_STOP_WAITING:
+ return 0; //todo
+ break;
+ case GQUIC_REGULAR_FRAME_PING:
+ return 0; //todo
+ break;
+ default: //Regular Frame Types
+ if(frame_type&GQUIC_SPECIAL_FRAME_STREAM)
{
- *used_len+=2;
+ ret=gquic_frame_type_stream(pstream, _context, payload, payload_len, used_len, frame_type, a_packet);
}
- *used_len+=1;
- *used_len+=read_stream_len(frame_type);
- *used_len+=read_offset_len(frame_type);
-
- if((quic_data_len-*used_len)<=4)
+ else if(frame_type&GQUIC_SPECIAL_FRAME_ACK)
{
- return QUIC_FALSE;
+ return 0; //todo
}
-
- strncpy((char*)&message_tag, quic_data+*used_len, 4);
- if(ntohl(message_tag)==CHLO || ntohl(message_tag)==SHLO || ntohl(message_tag)==REJ)
+ else if(frame_type&GQUIC_SPECIAL_FRAME_CONGEST_FB)
{
- return QUIC_TRUE;
+ return 0; //todo
}
- }
- else if(frame_type&ACK)
- {
- gquic_frame_type_ack(a_quic_stream, quic_data, quic_data_len, frame_type, used_len);
- }
- else
- {
- *used_len +=1;
- return QUIC_FALSE;
- }
+ else
+ {
+ return -1;
+ }
+ break;
}
}
- return QUIC_FALSE;
+ return APP_STATE_GIVEME;
}
-UINT8 parse_gquic_Q046(struct streaminfo *pstream, void* a_packet, char * payload, uint32_t payload_len, uint32_t *used_len, struct quic_stream* a_quic_stream, uint8_t pub_flags)
+
+//QUIC_DATA:is quic data pcap;QUIC_TRUE:is handshake pcap;QUIC_RETURN_DROPME:not quic protocol;
+int parse_gquic_Q046(struct streaminfo *pstream, struct _quic_context* _context, void *a_packet, char * payload, int payload_len, int *used_len)
{
- uint8_t frame_type;
- uint16_t tag_num=0;
- uint32_t stream_id, message_tag;
-
- if(!a_canRead(25, payload_len, *used_len))
- {
- return QUIC_RETURN_DROPME;
- }
-
- *used_len += 25;
-
+ unsigned char frame_type;
+ unsigned short tag_num=0;
+ unsigned int stream_id, message_tag;
+
while(*used_len < payload_len)
{
- a_readUInt8(&frame_type, payload, payload_len, used_len);
- if(frame_type & STREAM)
+ frame_type=payload[*used_len];
+ *used_len+=1; //skip frame_type
+
+ if(frame_type&IQUIC_FRAME_STREAM_HEX08)
{
- stream_id=get_stream_id(pstream, payload, frame_type, used_len);
- if(stream_id==1)
- {
- message_tag = a_pntoh32((void *)payload, *used_len);
- *used_len += 4;
- tag_num = a_pletoh16(payload, *used_len);
- *used_len += 2; //tag_num
- *used_len += 2; //padding
- switch(message_tag)
- {
- case CHLO: //MTAG_CHLO;
- if(a_quic_stream->st_client_hello.ext_tags==NULL && tag_num>0)
- {
- a_quic_stream->st_client_hello.ext_tags=(quic_tlv_t **)dictator_malloc(pstream->threadnum, tag_num*sizeof(quic_tlv_t*));
- a_quic_stream->st_client_hello.ext_tag_num = tag_num;
- }
-
- gquic_proc_tag(pstream, a_quic_stream, tag_num, C2S, a_packet, payload, payload_len, used_len);
-
- if(a_quic_stream->st_client_hello.server_name_len > 0 || a_quic_stream->st_client_hello.user_agent_len > 0)
- {
- quic_callPlugins(a_quic_stream, pstream, QUIC_CLIENT_HELLO_MASK, pstream->threadnum, a_packet);
- }
- break;
- default:
- break;
- }
- }
+ gquic_frame_type_stream(pstream, _context, payload, payload_len, used_len, frame_type, a_packet);
+ }
+ else
+ {
+ return 0; //todo
}
}
return QUIC_RETURN_NORM;
}
-UINT8 parse_gquic(struct streaminfo *pstream, void* a_packet, char * payload, uint32_t payload_len, uint32_t *used_len, struct quic_stream* a_quic_stream, uint8_t pub_flags)
-{
- int is_handshake=0;
- uint32_t pkt_num_len = 0;
- uint32_t skip_len=0;
-
- pkt_num_len=read_seq_num_len(pub_flags);
-
- //version ��
- if(!(PUBLIC_FLAG_VER&pub_flags!=0) && a_quic_stream->version && !a_quic_stream->version_cfm)
- {
- a_quic_stream->version_cfm = QUIC_TRUE;
- quic_callPlugins(a_quic_stream, pstream, QUIC_VERSION_MASK, pstream->threadnum, a_packet);
- MESA_handle_runtime_log(g_quic_param.logger, RLOG_LV_DEBUG, "QUIC_VERSION", "version: %u addr: %s", a_quic_stream->version, printaddr(&pstream->addr, pstream->threadnum));
- }
-
- skip_len=*used_len;
- is_handshake=is_handshake_pkt(a_quic_stream, pkt_num_len, payload, payload_len, &skip_len); // just identify
- switch(is_handshake)
- {
- case QUIC_TRUE: //handshake
- a_quic_stream->is_quic_stream = QUIC_TRUE;
- gquic_proc_unencrypt(pstream, a_quic_stream, pkt_num_len, a_packet, payload, payload_len, used_len);
- break;
- case QUIC_DATA: //ack or special stream
- a_quic_stream->is_quic_stream = QUIC_TRUE;
- break;
- default: //gquic data or not gquic packet
- if(!a_quic_stream->is_quic_stream)
- {
- return QUIC_RETURN_DROPME;
- }
-
- quic_callPlugins(a_quic_stream, pstream, QUIC_APPLICATION_DATA_MASK, pstream->threadnum, a_packet);
- break;
- }
-
- return QUIC_RETURN_NORM;
-}
-
-
//cid->version->nounce->pkt num->ahn hash(12)
-UINT8 gquic_process(struct streaminfo *pstream, struct quic_stream* a_quic_stream, int thread_seq, void* a_packet)
+int quic_process(struct streaminfo *pstream, struct _quic_context* _context, int thread_seq, void* a_packet)
{
- uint8_t pub_flags = 0;
- uint32_t used_len = 0;
- int ret=QUIC_RETURN_DROPME;
- enum GQUIC_VERSION is_gquic=GQUIC_UNKNOWN;
- struct udpdetail *udp_detail=(struct udpdetail *)pstream->pdetail;
-
- if(!a_quic_stream->is_quic_stream && udp_detail->datalen<=GQUIC_HEADER_LEN)
- {
- MESA_handle_runtime_log(g_quic_param.logger,
- RLOG_LV_DEBUG,
- "QUIC",
- "This is not quic (!a_quic_stream->is_quic_stream)=%d, or packet length is litter udp_detail->datalen<=GQUIC_HEADER_LEN(%d<=%d) addr: %s",
- !a_quic_stream->is_quic_stream,
- udp_detail->datalen,
- GQUIC_HEADER_LEN,
- printaddr(&pstream->addr, thread_seq));
- return QUIC_RETURN_DROPME;
- }
+ int used_len=0;
+ int ret=APP_STATE_GIVEME;
+ enum _QUIC_VERSION is_gquic=QUIC_VERSION_UNKNOWN;
+ struct udpdetail *udp_detail=pstream->pudpdetail;
if(udp_detail->pdata==NULL || udp_detail->datalen<=0)
{
- return QUIC_RETURN_NORM;
+ return APP_STATE_GIVEME;
}
- is_gquic=is_gquic_protocol(pstream, (char *)udp_detail->pdata, udp_detail->datalen, &pub_flags, &a_quic_stream->version, &used_len);
- if(is_gquic!=GQUIC_UNKNOWN)
+ is_gquic=is_quic_protocol(pstream, _context, (char *)udp_detail->pdata, udp_detail->datalen, &used_len);
+ if(is_gquic!=QUIC_VERSION_UNKNOWN)
{
- a_quic_stream->is_quic_stream=QUIC_TRUE;
- quic_callPlugins(a_quic_stream, pstream, QUIC_VERSION_MASK, thread_seq, a_packet);
-
+ if(_context->quic_info.quic_hdr.packet_number==1)
+ {
+ ret=quic_callPlugins(pstream, _context, &(_context->quic_info.quic_hdr.quic_version), sizeof(_context->quic_info.quic_hdr.quic_version), QUIC_VERSION_MASK, a_packet);
+ if(ret&APP_STATE_DROPME | ret&APP_STATE_DROPPKT)
+ {
+ return ret;
+ }
+ }
+
switch(is_gquic)
{
- case GQUIC_OTHERS:
- ret=parse_gquic(pstream, a_packet, (char *)udp_detail->pdata, udp_detail->datalen, &used_len, a_quic_stream, pub_flags);
+ case GQUIC_VERSION_Q043:
+ ret=gquic_proc_unencrypt(pstream, _context, a_packet, (char *)udp_detail->pdata, udp_detail->datalen, &used_len);
break;
- case GQUIC_Q046:
- ret=parse_gquic_Q046(pstream, a_packet, (char *)udp_detail->pdata, udp_detail->datalen, &used_len, a_quic_stream, pub_flags);
+ case GQUIC_VERSION_Q046:
+ ret=parse_gquic_Q046(pstream, _context, a_packet, (char *)udp_detail->pdata, udp_detail->datalen, &used_len);
break;
default:
break;
}
}
- if(a_quic_stream->is_quic_stream==QUIC_TRUE)
+ if(_context->is_quic==QUIC_TRUE)
{
- return QUIC_RETURN_NORM;
- }
-
- return ret;
-}
-
-
-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 0; // modify by liuxueli 20200522
- //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 APP_STATE_GIVEME;
}
- return 1;
+ return APP_STATE_DROPME;;
}
diff --git a/src/gquic_process.h b/src/gquic_process.h
index b7d3f0c..be68d42 100644
--- a/src/gquic_process.h
+++ b/src/gquic_process.h
@@ -1,5 +1,5 @@
/*
- * gquic_process.h
+ * quic_process.h
*
* Created on: 2019��4��2��
* Author: root
@@ -14,94 +14,177 @@
#include "gquic.h"
-#define VERSION_LEN 4
-#define VER_Q046 0x51303436
-/**************************************************************************/
-/* Public flag */
-/**************************************************************************/
-
+//#define VERSION_LEN 4
+//#define VER_Q046
+
+#define GQUIC_PUBLIC_FLAG_VERSION 0x01
+#define GQUIC_PUBLIC_FLAG_RST 0x02
+#define GQUIC_PUBLIC_FLAG_NONCE 0x04
+#define GQUIC_PUBLIC_FLAG_CID 0x08
+#define GQUIC_PUBLIC_FLAG_PKT_NUM 0x30
+
+//https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
+
+enum _QUIC_VERSION
+{
+ QUIC_VERSION_UNKNOWN=0,
+ //google
+ GQUIC_VERSION_Q001=0x51303031,
+ GQUIC_VERSION_Q002=0x51303032,
+ GQUIC_VERSION_Q003=0x51303033,
+ GQUIC_VERSION_Q004=0x51303034,
+ GQUIC_VERSION_Q005=0x51303035,
+ GQUIC_VERSION_Q006=0x51303036,
+ GQUIC_VERSION_Q007=0x51303037,
+ GQUIC_VERSION_Q008=0x51303038,
+ GQUIC_VERSION_Q009=0x51303039,
+
+ GQUIC_VERSION_Q010=0x51303130,
+ GQUIC_VERSION_Q011=0x51303131,
+ GQUIC_VERSION_Q012=0x51303132,
+ GQUIC_VERSION_Q013=0x51303133,
+ GQUIC_VERSION_Q014=0x51303134,
+ GQUIC_VERSION_Q015=0x51303135,
+ GQUIC_VERSION_Q016=0x51303136,
+ GQUIC_VERSION_Q017=0x51303137,
+ GQUIC_VERSION_Q018=0x51303138,
+ GQUIC_VERSION_Q019=0x51303139,
+
+ GQUIC_VERSION_Q020=0x51303230,
+ GQUIC_VERSION_Q021=0x51303231,
+ GQUIC_VERSION_Q022=0x51303332,
+ GQUIC_VERSION_Q023=0x51303333,
+ GQUIC_VERSION_Q024=0x51303234,
+ GQUIC_VERSION_Q025=0x51303235,
+ GQUIC_VERSION_Q026=0x51303236,
+ GQUIC_VERSION_Q027=0x51303237,
+ GQUIC_VERSION_Q028=0x51303238,
+ GQUIC_VERSION_Q029=0x51303239,
+
+ GQUIC_VERSION_Q030=0x51303330,
+ GQUIC_VERSION_Q031=0x51303331,
+ GQUIC_VERSION_Q032=0x51303332,
+ GQUIC_VERSION_Q033=0x51303333,
+ GQUIC_VERSION_Q034=0x51303334,
+ GQUIC_VERSION_Q035=0x51303335,
+ GQUIC_VERSION_Q036=0x51303336,
+ GQUIC_VERSION_Q037=0x51303337,
+ GQUIC_VERSION_Q038=0x51303338,
+ GQUIC_VERSION_Q039=0x51303339,
+
+ GQUIC_VERSION_Q040=0x51303430,
+ GQUIC_VERSION_Q041=0x51303431,
+ GQUIC_VERSION_Q042=0x51303432,
+ GQUIC_VERSION_Q043=0x51303433,
+ GQUIC_VERSION_Q044=0x51303434,
+ GQUIC_VERSION_Q045=0x51303435,
+ GQUIC_VERSION_Q046=0x51303436,
+ GQUIC_VERSION_Q047=0x51303437,
+ GQUIC_VERSION_Q048=0x51303438, //Google QUIC with TLS
+ GQUIC_VERSION_Q049=0x51303439, //Google QUIC with TLS
+
+ GQUIC_VERSION_Q050=0x51303530,
+ GQUIC_VERSION_Q051=0x51303531,
+ GQUIC_VERSION_Q052=0x51303532,
+ GQUIC_VERSION_Q053=0x51303533,
+ GQUIC_VERSION_Q054=0x51303534,
+ GQUIC_VERSION_Q055=0x51303535,
+ GQUIC_VERSION_Q056=0x51303536,
+ GQUIC_VERSION_Q057=0x51303537,
+ GQUIC_VERSION_Q058=0x51303538,
+ GQUIC_VERSION_Q059=0x51303539,
+
+ GQUIC_VERSION_Q099=0x51303939,
+
+ //Google Proxied QUIC
+ PQUIC_VERSION_PROX=0x50524f58
+ //GOQUIC_VERSION_GO=0x51474f[0-255],
+ //quicly
+ //QUICKLY_VERSION_QUICLY=0x91c170[0-255]
+
+ //IETF
+ //IQUIC_VERSION_=0xf10000
-#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
+struct _gquic_reset_public_header
+{
+ unsigned char public_flags;
+ unsigned long long connection_id;
+ unsigned int tag;
};
-//#define PUBLIC_FLAG_MULTIPATH 0x40
-#define UNUSE 0x80
-#define MSG_AUTH_HASH_LEN 12
-#define PUB_HEAD_SEQ_SFT 4
+//GQIIC Frame type
+#define GQUIC_SPECIAL_FRAME_FLAG 0xE0 // Special Frame Types
+#define GQUIC_SPECIAL_FRAME_STREAM 0x80
+#define GQUIC_SPECIAL_FRAME_ACK 0x40
+#define GQUIC_SPECIAL_FRAME_CONGEST_FB 0x20
+
+#define GQUIC_SPECIAL_FRAME_STREAM_FIN 0x40 // FIN
+#define GQUIC_SPECIAL_FRAME_STREAM_DLEN 0x20 //stream length
+#define GQUIC_SPECIAL_FRAME_STREAM_OFFSET 0x1C //offset header field
+#define GQUIC_SPECIAL_FRAME_STREAM_ID 0x03 //offset header field
+
+#define GQUIC_REGULAR_FRAME_PADDING 0x00
+#define GQUIC_REGULAR_FRAME_RST_STREAM 0x01
+#define GQUIC_REGULAR_FRAME_CONNECTION_CLOSE 0x02
+#define GQUIC_REGULAR_FRAME_GOAWAY 0x03
+#define GQUIC_REGULAR_FRAME_WINDOW_UPDATE 0x04
+#define GQUIC_REGULAR_FRAME_BLOCKED 0x05
+#define GQUIC_REGULAR_FRAME_STOP_WAITING 0x06
+#define GQUIC_REGULAR_FRAME_PING 0x07
+
+#define GQUIC_SPECIAL_FRAME_FLAG 0xE0 // Special Frame Types
+#define GQUIC_SPECIAL_FRAME_STREAM 0x80
+#define GQUIC_SPECIAL_FRAME_ACK 0x40
+#define GQUIC_SPECIAL_FRAME_CONGEST_FB 0x20
+
+#define GQUIC_SPECIAL_FRAME_STREAM_FIN 0x40 // FIN
+#define GQUIC_SPECIAL_FRAME_STREAM_DLEN 0x20 //stream length
+#define GQUIC_SPECIAL_FRAME_STREAM_OFFSET 0x1C //offset header field
+#define GQUIC_SPECIAL_FRAME_STREAM_ID 0x03 //offset header field
+
+#define GQUIC_REGULAR_FRAME_PADDING 0x00
+#define GQUIC_REGULAR_FRAME_RST_STREAM 0x01
+#define GQUIC_REGULAR_FRAME_CONNECTION_CLOSE 0x02
+#define GQUIC_REGULAR_FRAME_GOAWAY 0x03
+#define GQUIC_REGULAR_FRAME_WINDOW_UPDATE 0x04
+#define GQUIC_REGULAR_FRAME_BLOCKED 0x05
+#define GQUIC_REGULAR_FRAME_STOP_WAITING 0x06
+#define GQUIC_REGULAR_FRAME_PING 0x07
+
+//IQIIC Frame type (GQUIC_Q046 is iQUIC 17)
+#define IQUIC_FRAME_PADDING 0x00
+#define IQUIC_FRAME_PING 0x10
+#define IQUIC_FRAME_ACK_HEX02 0x20
+#define IQUIC_FRAME_ACK_HEX03 0x30
+#define IQUIC_FRAME_RESET_STREAM 0x40
+#define IQUIC_FRAME_STOP_SENDING 0x50
+#define IQUIC_FRAME_CRYPTO 0x60
+#define IQUIC_FRAME_NEW_TOKEN 0x70
+#define IQUIC_FRAME_STREAM_HEX08 0x80
+#define IQUIC_FRAME_STREAM_HEX09 0x90
+#define IQUIC_FRAME_STREAM_HEX0A 0xA0
+#define IQUIC_FRAME_STREAM_HEX0B 0xB0
+#define IQUIC_FRAME_STREAM_HEX0C 0xC0
+#define IQUIC_FRAME_STREAM_HEX0D 0xD0
+#define IQUIC_FRAME_STREAM_HEX0E 0xE0
+#define IQUIC_FRAME_STREAM_HEX0F 0xF0
+#define IQUIC_FRAME_MAX_DATA 0x01
+#define IQUIC_FRAME_MAX_STREAM_DATA 0x11
+#define IQUIC_FRAME_MAX_STREAMS_HEX12 0x21
+#define IQUIC_FRAME_MAX_STREAMS_HEX13 0x31
+#define IQUIC_FRAME_DATA_BLOCKED 0x41
+#define IQUIC_FRAME_STREAM_DATA_BLOCKED 0x51
+#define IQUIC_FRAME_STREAMS_BLOCKED_HEX16 0x61
+#define IQUIC_FRAME_STREAMS_BLOCKED_HEX17 0x71
+#define IQUIC_FRAME_NEW_CONNECTION_ID 0x81
+#define IQUIC_FRAME_RETIRE_CONNECTION_ID 0x91
+#define IQUIC_FRAME_PATH_CHALLENGE 0xA1
+#define IQUIC_FRAME_PATH_RESPONSE 0xB1
+#define IQUIC_FRAME_CONNECTION_CLOSE_HEX1C 0xC1
+#define IQUIC_FRAME_CONNECTION_CLOSE_HEX1D 0xD1
-/**************************************************************************/
-/* 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 */
@@ -111,40 +194,6 @@ enum frame_type_t{
#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 */
@@ -196,15 +245,7 @@ struct gquic_pkt_hdr{
-UINT8 gquic_process(struct streaminfo *pstream, struct quic_stream* a_quic_stream, int thread_seq, void* a_packet);
-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, UINT8 frame_type, UINT32 *skip_len);
-UINT32 read_seq_num_len(UINT8 flags);
-int read_conn_id_len(UINT8 flags);
+int quic_process(struct streaminfo *pstream, struct _quic_context* _context, int thread_seq, void* a_packet);
#endif
diff --git a/src/quic_analysis.c b/src/quic_analysis.c
index 59cd4bd..f0b20be 100644
--- a/src/quic_analysis.c
+++ b/src/quic_analysis.c
@@ -12,7 +12,7 @@
#include <MESA/MESA_handle_logger.h>
#include <MESA/MESA_prof_load.h>
-struct quic_param_t g_quic_param;
+struct _quic_param_t g_quic_param;
const char *g_quic_proto_conffile="./conf/quic/main.conf";
const char *g_quic_regionname_conffile="./conf/quic/quic.conf";
@@ -39,47 +39,19 @@ static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL;
const char QUIC_VERSION_20200522=0;
-
int quic_init_stream(void **pme, int thread_seq)
{
- struct quic_stream *a_quic_stream=(struct quic_stream *)*pme;
-
- a_quic_stream=(struct quic_stream *)dictator_malloc(thread_seq, sizeof(struct quic_stream));
- memset(a_quic_stream,0,sizeof(struct quic_stream));
-
- a_quic_stream->output_region_flag = g_quic_param.quic_interested_region_flag;
- a_quic_stream->output_region_mask = QUIC_INTEREST_KEY_MASK;
+ struct _quic_context *_context=(struct _quic_context *)*pme;
- 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->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;
+ _context=(struct _quic_context *)dictator_malloc(thread_seq, sizeof(struct _quic_context));
+ memset(_context, 0, sizeof(struct _quic_context));
- *pme = (void*)a_quic_stream;
+ *pme=(void*)_context;
return 0;
}
-void quic_release_clientHello(int thread_seq, struct quic_client_hello* st_client_hello)
-{
- if(st_client_hello!=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_exts(int thread_seq, quic_tlv_t** ext_tags, UINT16 ext_tag_num)
+void quic_release_exts(int thread_seq, quic_tlv_t *ext_tags, int ext_tag_num)
{
int i=0;
@@ -87,62 +59,48 @@ void quic_release_exts(int thread_seq, quic_tlv_t** ext_tags, UINT16 ext_tag_num
{
for(i=0; i<ext_tag_num; i++)
{
- if(ext_tags[i] != NULL)
+ if(ext_tags[i].value!=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;
+ dictator_free(thread_seq, ext_tags[i].value);
+ ext_tags[i].value=NULL;
}
}
dictator_free(thread_seq, ext_tags);
ext_tags=NULL;
}
+
}
void quic_release_stream(struct streaminfo *a_tcp, void** pme, int thread_seq)
{
- struct quic_stream *a_quic_stream = (struct quic_stream *)*pme;
- if(NULL!=a_quic_stream)
- {
- a_quic_stream->fin_flag = QUIC_TRUE;
-
- if(NULL!=a_quic_stream->business)
+ struct _quic_context *_context = (struct _quic_context *)*pme;
+ if(NULL!=_context)
+ {
+ if(_context->quic_info.client_hello!=NULL)
{
- 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;
+ quic_release_exts(thread_seq, _context->quic_info.client_hello->ext_tags, _context->quic_info.client_hello->ext_tag_num);
+ dictator_free(thread_seq, _context->quic_info.client_hello);
+ _context->quic_info.client_hello=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)
+
+ if(_context->quic_info.server_hello!=NULL)
{
- dictator_free(thread_seq,a_quic_stream->common_cert.ptr_value);
- a_quic_stream->common_cert.ptr_value = NULL;
+ quic_release_exts(thread_seq, _context->quic_info.server_hello->ext_tags, _context->quic_info.server_hello->ext_tag_num);
+ dictator_free(thread_seq, _context->quic_info.server_hello);
+ _context->quic_info.server_hello=NULL;
}
- if(NULL!=a_quic_stream->cached_cert.ptr_value)
+
+ if(_context->quic_info.rej!=NULL)
{
- dictator_free(thread_seq,a_quic_stream->cached_cert.ptr_value);
- a_quic_stream->cached_cert.ptr_value = NULL;
+ quic_release_exts(thread_seq, _context->quic_info.rej->ext_tags, _context->quic_info.rej->ext_tag_num);
+ dictator_free(thread_seq, _context->quic_info.rej);
+ _context->quic_info.rej=NULL;
}
-
- quic_release_exts(thread_seq, a_quic_stream->st_client_hello.ext_tags, a_quic_stream->st_client_hello.ext_tag_num);
- quic_release_exts(thread_seq, a_quic_stream->st_server_hello.ext_tags, a_quic_stream->st_server_hello.ext_tag_num);
- dictator_free(thread_seq,a_quic_stream);
- a_quic_stream = NULL;
+ dictator_free(thread_seq, _context);
+ _context=NULL;
+ *pme=NULL;
}
return;
@@ -157,7 +115,7 @@ extern "C" int QUIC_INIT(void)
int region_id=0;
char region_name[REGION_NAME_LEN]={0};
- memset(&g_quic_param,0,sizeof(struct quic_param_t));
+ memset(&g_quic_param,0,sizeof(struct _quic_param_t));
MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "LOG_LEVEL", &level, RLOG_LV_FATAL);
MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "LOG_PATH", log_path, sizeof(log_path), "./log/quic/quic");
@@ -278,8 +236,8 @@ extern "C" long long QUIC_FLAG_CHANGE(char* flag_str)
extern "C" char QUIC_ENTRY(struct streaminfo *pstream, void**pme, int thread_seq, void *a_packet)
{
- uint8_t return_val=0;
- struct quic_stream *a_quic_stream=(struct quic_stream *)*pme;
+ int ret=0;
+ struct _quic_context *_context=(struct _quic_context *)*pme;
if(g_quic_param.quic_interested_region_flag<QUIC_KEY)
{
@@ -296,28 +254,27 @@ extern "C" char QUIC_ENTRY(struct streaminfo *pstream, void**pme, int thread_seq
if(*pme==NULL)
{
quic_init_stream(pme, thread_seq);
- a_quic_stream=(struct quic_stream *)*pme;
+ _context=(struct _quic_context *)*pme;
}
switch(pstream->opstate)
{
case OP_STATE_PENDING:
case OP_STATE_DATA:
- return_val=gquic_process(pstream, a_quic_stream, thread_seq, a_packet);
+ ret=quic_process(pstream, _context, thread_seq, a_packet);
break;
case OP_STATE_CLOSE:
- a_quic_stream->fin_flag=QUIC_TRUE;
- return_val=gquic_process(pstream, a_quic_stream, thread_seq, a_packet);
+ ret=quic_process(pstream, _context, thread_seq, a_packet);
break;
default:
break;
}
- if(return_val==QUIC_RETURN_DROPME || pstream->opstate==OP_STATE_CLOSE)
+ if(ret&APP_STATE_DROPME|| pstream->opstate==OP_STATE_CLOSE)
{
quic_release_stream(pstream, pme, thread_seq);
*pme=NULL;
- return APP_STATE_DROPME;
+ return ret;
}
return APP_STATE_GIVEME;
diff --git a/src/quic_analysis.h b/src/quic_analysis.h
index 7423504..51ccd57 100644
--- a/src/quic_analysis.h
+++ b/src/quic_analysis.h
@@ -1,15 +1,7 @@
-/*
- * quic_analysis.h
- *
- * Created on: 2019��4��2��
- * Author: root
- */
+#ifndef _QUIC_ANALYSIS_H_
+#define _QUIC_ANALYSIS_H_
-#ifndef SRC_QUIC_ANALYSIS_H_
-#define SRC_QUIC_ANALYSIS_H_
-
-#include <stdint.h>
-#include "quic_util.h"
+#include "gquic.h"
#define QUIC_TRUE 0x01
#define QUIC_FALSE 0x00
@@ -17,24 +9,14 @@
#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
+struct _quic_param_t
{
unsigned long long quic_interested_region_flag;
unsigned long long quic_region_cnt;
@@ -54,7 +36,18 @@ enum quic_mes_type{
MSG_UNKNOWN = 255
};
-void quic_release_exts(int thread_seq, quic_tlv_t** ext_tags, UINT16 ext_tag_num);
+struct _quic_context
+{
+ int is_quic;
+ int link_state;
+ void *business_pme;
+ struct _quic_info quic_info;
+};
+
+
+extern struct _quic_param_t g_quic_param;
+
+void quic_release_exts(int thread_seq, quic_tlv_t *ext_tags, int ext_tag_num);
#endif /* SRC_QUIC_ANALYSIS_H_ */
diff --git a/src/quic_callback.c b/src/quic_callback.c
index 81824c5..b28b04f 100644
--- a/src/quic_callback.c
+++ b/src/quic_callback.c
@@ -1,64 +1,3 @@
-/*
- * 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;
-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_callPlugins(struct quic_stream *a_quic_stream, struct streaminfo *pstream, enum quic_interested_region region_mask, int thread_seq, void *a_packet)
-{
- stSessionInfo session_info;
- unsigned long long region_flag=a_quic_stream->output_region_flag;
-
- region_flag = (region_flag >> 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)<<region_mask);
- session_info.session_state = quic_getLinkState(a_quic_stream) ;
- session_info.app_info = (void*)a_quic_stream;
- a_quic_stream->business->return_value = PROT_PROCESS(&session_info, &(a_quic_stream->business->param),thread_seq,pstream, a_packet);
- }
- }
-
- return QUIC_RETURN_NORM;
-}
diff --git a/src/quic_callback.h b/src/quic_callback.h
index 4402146..7fccf7f 100644
--- a/src/quic_callback.h
+++ b/src/quic_callback.h
@@ -7,12 +7,5 @@
#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, enum quic_interested_region region_mask, 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_version.cpp b/src/quic_version.cpp
new file mode 100644
index 0000000..569172f
--- /dev/null
+++ b/src/quic_version.cpp
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "gquic.h"
+#include "gquic_process.h"
+
+int quic_version_int2string(unsigned int version, char *buff, int buff_len)
+{
+ if(version>0 && version<=GQUIC_VERSION_Q099)
+ {
+ snprintf(buff, buff_len, "Google QUIC %02d", (((version>>8)&0x0000000F)*10) + (version&0x0000000F));
+ return 0;
+ }
+
+ return -1;
+}
+