2020-05-12 12:18:02 +08:00
|
|
|
|
/*
|
|
|
|
|
|
* gquic_process.c
|
|
|
|
|
|
*
|
|
|
|
|
|
* Created on: 2019<EFBFBD><EFBFBD>4<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>
|
|
|
|
|
|
* Author: root
|
|
|
|
|
|
*/
|
|
|
|
|
|
#include "gquic_process.h"
|
|
|
|
|
|
#include "quic_analysis.h"
|
|
|
|
|
|
#include "quic_callback.h"
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include<assert.h>
|
2020-05-22 18:44:00 +08:00
|
|
|
|
#include <MESA/MESA_handle_logger.h>
|
2020-05-12 12:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define C2S 0x01
|
|
|
|
|
|
#define S2C 0x02
|
|
|
|
|
|
#define GQUIC_HANDSHAKE_LEN 12+1+1+4+4
|
|
|
|
|
|
#define DIVERSIFICATION_NONCE_LEN 32
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
extern struct quic_param_t g_quic_param;
|
|
|
|
|
|
|
|
|
|
|
|
enum gquic_type
|
|
|
|
|
|
{
|
|
|
|
|
|
GQUIC=1,
|
|
|
|
|
|
UNKNOWN_QUIC_TYPE
|
2020-05-12 12:18:02 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
enum gquic_handshake_type
|
|
|
|
|
|
{
|
|
|
|
|
|
QUIC_Crypto=1,
|
|
|
|
|
|
UNKNOWN_HANDSHAKE_TYPE
|
2020-05-12 12:18:02 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UINT32 get_stream_id(struct streaminfo *pstream, char* quic_data, UINT8 frame_type, UINT32 *skip_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)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
stream_id=quic_data[*skip_len];
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
stream_id=a_pletoh16((void *)quic_data, *skip_len);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
stream_id=a_pletoh24((void *)quic_data, *skip_len);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
stream_id=a_pletoh32((void *)quic_data, *skip_len);
|
|
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
*skip_len+=len_stream; // stream ID length
|
2020-05-12 12:18:02 +08:00
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
if(frame_type&STREAM_D)
|
|
|
|
|
|
{
|
|
|
|
|
|
data_length=ntohs(a_pletoh16((void *)quic_data, *skip_len));
|
|
|
|
|
|
*skip_len+=2; //data length
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
len_offset=read_offset_len(frame_type);
|
|
|
|
|
|
*skip_len+=len_offset;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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,
|
|
|
|
|
|
printaddr(&pstream->addr, pstream->threadnum));
|
|
|
|
|
|
|
|
|
|
|
|
return stream_id;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UINT32 get_packet_number(char* g_data_t, UINT32 offset, UINT8 pkn_len)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch(pkn_len)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
return g_data_t[offset];
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
return ntohs(a_pletoh16((void *)g_data_t, offset));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 4:
|
|
|
|
|
|
return a_pletoh32((void *)g_data_t, offset);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return a_pletoh48((void *)g_data_t, offset);
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t is_q064=0;
|
|
|
|
|
|
uint64_t connection_id = 0;
|
|
|
|
|
|
int connection_id_len = 0;
|
|
|
|
|
|
enum GQUIC_VERSION quic_version=GQUIC_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
|
|
if(a_canRead(5, payload_len, *skip_len))
|
|
|
|
|
|
{
|
|
|
|
|
|
*skip_len+=1;
|
|
|
|
|
|
strncpy((char*)&is_q064, payload+(*skip_len), 4);
|
|
|
|
|
|
if(ntohl(is_q064)==VER_Q046)
|
|
|
|
|
|
{
|
|
|
|
|
|
*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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*skip_len-=1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*pub_flags=payload[*skip_len]; // public flags
|
|
|
|
|
|
*skip_len+=1;
|
|
|
|
|
|
|
|
|
|
|
|
if(*pub_flags>PACKET_PUBLIC_FLAGS_MAX)
|
|
|
|
|
|
{
|
|
|
|
|
|
return quic_version;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
*skip_len += 2;
|
|
|
|
|
|
*version=(payload[*skip_len]&0x0f)*10 + (payload[*skip_len+1]&0x0f);
|
|
|
|
|
|
*skip_len += 2;
|
|
|
|
|
|
quic_version=GQUIC_OTHERS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(*pub_flags==PUBLIC_FLAG_NONCE)
|
|
|
|
|
|
{
|
|
|
|
|
|
*skip_len+=32; //diversification nonce
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
//message authentication hash
|
|
|
|
|
|
*skip_len+=MSG_AUTH_HASH_LEN;
|
|
|
|
|
|
|
|
|
|
|
|
if(*version>0 && *version<34)
|
|
|
|
|
|
{
|
|
|
|
|
|
*skip_len+=1; //private flags
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
|
pstream->curdir,
|
|
|
|
|
|
printaddr(&pstream->addr, pstream->threadnum));
|
|
|
|
|
|
|
|
|
|
|
|
return quic_version;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
tag_offset_end=a_pletoh32(quic_data, *used_len);
|
|
|
|
|
|
*used_len+=4;
|
|
|
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
|
{
|
|
|
|
|
|
return ;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch(tag_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case TAG_PAD:
|
2020-05-12 12:18:02 +08:00
|
|
|
|
break;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
break;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
break;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
break;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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,
|
|
|
|
|
|
RLOG_LV_DEBUG,
|
|
|
|
|
|
"QUIC_SNI",
|
|
|
|
|
|
"SNI: %s addr: %s",
|
|
|
|
|
|
a_quic_stream->st_client_hello.server_name,
|
|
|
|
|
|
printaddr(&pstream->addr, pstream->threadnum));
|
|
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
num++;
|
|
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
tag_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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
|
|
|
|
|
UINT32 len_largest_observed=0, len_missing_packet=0;
|
|
|
|
|
|
|
|
|
|
|
|
*used_len+=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
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
*used_len += len_largest_observed;
|
|
|
|
|
|
*used_len += 2; //ack delay time
|
|
|
|
|
|
strncpy((char*)&num_timestamp, quic_data+*used_len,1);
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
if(num_timestamp > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
*used_len += 4;
|
|
|
|
|
|
*used_len += (num_timestamp - 1)*(1+2);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
if(frame_type & ACK_N)
|
|
|
|
|
|
{
|
|
|
|
|
|
strncpy((char*)&num_ranges, quic_data+*used_len,1);
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
|
|
|
|
|
|
*used_len += num_ranges*(len_missing_packet+1);
|
|
|
|
|
|
|
|
|
|
|
|
strncpy((char*)&num_revived, quic_data+*used_len,1);
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
|
|
|
|
|
|
//Num Revived x Length Largest Observed
|
|
|
|
|
|
*used_len += num_revived*len_largest_observed;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
*used_len += len_largest_observed; //Largest Acked
|
|
|
|
|
|
*used_len += 2; //Largest Acked Delta Time
|
|
|
|
|
|
|
|
|
|
|
|
if(frame_type & ACK_N) //Ack Block
|
|
|
|
|
|
{
|
|
|
|
|
|
strncpy((char*)&num_blocks, quic_data+*used_len,1);
|
|
|
|
|
|
*used_len += 1;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
*used_len += len_missing_packet; //First Ack Block Length
|
|
|
|
|
|
if(num_blocks)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Gap to next block
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
num_blocks -= 1;
|
|
|
|
|
|
*used_len += (num_blocks - 1)*len_missing_packet;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
strncpy((char*)&num_timestamp, quic_data+*used_len,1); //Timestamp
|
|
|
|
|
|
*used_len += 1;
|
|
|
|
|
|
if(num_timestamp > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
*used_len += 1; //Delta Largest Acked
|
|
|
|
|
|
*used_len += 4; //Time Since Largest Acked
|
|
|
|
|
|
|
|
|
|
|
|
//Num Timestamp x (Delta Largest Acked + Time Since Previous Timestamp)
|
|
|
|
|
|
*used_len += (num_timestamp - 1)*(1+2);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
*used_len+=1;
|
|
|
|
|
|
|
|
|
|
|
|
switch(frame_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case RST_STREAM:
|
|
|
|
|
|
*used_len +=4; //stream id
|
|
|
|
|
|
*used_len+=8; //Byte Offset
|
|
|
|
|
|
*used_len+=4; //Error Code
|
|
|
|
|
|
a_quic_stream->fin_flag=QUIC_TRUE;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CONNECTION_CLOSE:
|
|
|
|
|
|
len_reason = 0;
|
|
|
|
|
|
*used_len += 4; //Error Code
|
|
|
|
|
|
len_reason = a_pntoh16(quic_data, *used_len); //Reason Phrase Length
|
|
|
|
|
|
*used_len += 2;
|
|
|
|
|
|
//Reason Phrase,If length remaining == len_reason, it is Connection Close
|
|
|
|
|
|
if(get_remaining_len(quic_data_len, *used_len) == len_reason)
|
|
|
|
|
|
{
|
|
|
|
|
|
return QUIC_DATA;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
a_quic_stream->fin_flag=(a_quic_stream->fin_flag==QUIC_FALSE) ? QUIC_HALF_CLOSE : QUIC_TRUE;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GOAWAY:
|
|
|
|
|
|
len_reason = 0;
|
|
|
|
|
|
*used_len += 4; //Error Code
|
|
|
|
|
|
*used_len += 4; //Last Good Stream ID
|
|
|
|
|
|
len_reason = a_pntoh16(quic_data, *used_len); //Reason Phrase Length
|
|
|
|
|
|
*used_len += 2;
|
|
|
|
|
|
*used_len += len_reason; //Reason Phrase
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WINDOW_UPDATE:
|
|
|
|
|
|
*used_len += 4; //Stream ID
|
|
|
|
|
|
*used_len += 8; //Byte Offset
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BLOCKED:
|
|
|
|
|
|
*used_len += 4; //Stream ID
|
|
|
|
|
|
break;
|
|
|
|
|
|
case STOP_WAITING:
|
|
|
|
|
|
//No longer Entropy after Q034
|
|
|
|
|
|
if(a_quic_stream->version < 34)
|
|
|
|
|
|
{
|
|
|
|
|
|
*used_len += 1; // Send Entropy
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
//Least Unacked Delta
|
|
|
|
|
|
*used_len += pkt_num_len;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case PING: //No Payload
|
|
|
|
|
|
case PADDING:
|
|
|
|
|
|
default:
|
|
|
|
|
|
return QUIC_FALSE;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return QUIC_TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
//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;
|
|
|
|
|
|
|
|
|
|
|
|
while(*used_len<quic_data_len)
|
|
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
ret=gquic_frame_type_stream(pstream, a_quic_stream, quic_data, quic_data_len, frame_type, used_len, a_packet);
|
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
|
ret=QUIC_FALSE;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
if(ret!=QUIC_TRUE)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
//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)
|
|
|
|
|
|
{
|
|
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if(frame_type&STREAM)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(frame_type&STREAM_D)
|
|
|
|
|
|
{
|
|
|
|
|
|
*used_len+=2;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
*used_len+=1;
|
|
|
|
|
|
*used_len+=read_stream_len(frame_type);
|
|
|
|
|
|
*used_len+=read_offset_len(frame_type);
|
|
|
|
|
|
|
|
|
|
|
|
if((quic_data_len-*used_len)<=4)
|
|
|
|
|
|
{
|
|
|
|
|
|
return QUIC_FALSE;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
strncpy((char*)&message_tag, quic_data+*used_len, 4);
|
|
|
|
|
|
if(ntohl(message_tag)==CHLO || ntohl(message_tag)==SHLO || ntohl(message_tag)==REJ)
|
|
|
|
|
|
{
|
|
|
|
|
|
return QUIC_TRUE;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
return QUIC_FALSE;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t frame_type;
|
|
|
|
|
|
uint16_t tag_num=0;
|
|
|
|
|
|
uint32_t stream_id, message_tag;
|
|
|
|
|
|
|
|
|
|
|
|
if(!a_canRead(25, payload_len, *used_len))
|
|
|
|
|
|
{
|
2020-05-12 12:18:02 +08:00
|
|
|
|
return QUIC_RETURN_DROPME;
|
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
*used_len += 25;
|
|
|
|
|
|
|
|
|
|
|
|
while(*used_len < payload_len)
|
|
|
|
|
|
{
|
|
|
|
|
|
a_readUInt8(&frame_type, payload, payload_len, used_len);
|
|
|
|
|
|
if(frame_type & STREAM)
|
|
|
|
|
|
{
|
|
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
|
return QUIC_RETURN_NORM;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
uint32_t pkt_num_len = 0;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
uint32_t skip_len=0;
|
|
|
|
|
|
|
|
|
|
|
|
pkt_num_len=read_seq_num_len(pub_flags);
|
|
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
|
//version Э<><D0AD>
|
2020-05-22 18:44:00 +08:00
|
|
|
|
if(!(PUBLIC_FLAG_VER&pub_flags!=0) && a_quic_stream->version && !a_quic_stream->version_cfm)
|
|
|
|
|
|
{
|
2020-05-12 12:18:02 +08:00
|
|
|
|
a_quic_stream->version_cfm = QUIC_TRUE;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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));
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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
|
2020-05-12 12:18:02 +08:00
|
|
|
|
a_quic_stream->is_quic_stream = QUIC_TRUE;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
return QUIC_RETURN_NORM;
|
|
|
|
|
|
}
|
2020-05-12 12:18:02 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//cid->version->nounce->pkt num->ahn hash(12)
|
2020-05-22 18:44:00 +08:00
|
|
|
|
UINT8 gquic_process(struct streaminfo *pstream, struct quic_stream* a_quic_stream, 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));
|
2020-05-12 12:18:02 +08:00
|
|
|
|
return QUIC_RETURN_DROPME;
|
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
if(udp_detail->pdata==NULL || udp_detail->datalen<=0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return QUIC_RETURN_NORM;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
a_quic_stream->is_quic_stream=QUIC_TRUE;
|
|
|
|
|
|
quic_callPlugins(a_quic_stream, pstream, QUIC_VERSION_MASK, thread_seq, a_packet);
|
2020-05-12 12:18:02 +08:00
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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);
|
|
|
|
|
|
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);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
if(a_quic_stream->is_quic_stream==QUIC_TRUE)
|
|
|
|
|
|
{
|
|
|
|
|
|
return QUIC_RETURN_NORM;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
UINT32 read_offset_len(UINT8 frame_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch((frame_type&STREAM_OOO)>>2)
|
|
|
|
|
|
{
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 0:
|
|
|
|
|
|
return 0;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 1:
|
|
|
|
|
|
return 2;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 2:
|
|
|
|
|
|
return 3;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 3:
|
|
|
|
|
|
return 4;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 4:
|
|
|
|
|
|
return 5;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 5:
|
|
|
|
|
|
return 6;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 6:
|
|
|
|
|
|
return 7;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case 7:
|
|
|
|
|
|
return 8;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
default:
|
2020-05-22 18:44:00 +08:00
|
|
|
|
break;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
UINT32 read_stream_len(UINT8 frame_type)
|
|
|
|
|
|
{
|
2020-05-12 12:18:02 +08:00
|
|
|
|
UINT32 stream_len = 0;
|
2020-05-22 18:44:00 +08:00
|
|
|
|
switch(frame_type&STREAM_SS)
|
|
|
|
|
|
{
|
2020-05-12 12:18:02 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
|
return stream_len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
int read_conn_id_len(UINT8 flags)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (flags&BYTE_CNTID_8)
|
|
|
|
|
|
{
|
2020-05-12 12:18:02 +08:00
|
|
|
|
case BYTE_CNTID_8:
|
|
|
|
|
|
return 8;
|
|
|
|
|
|
case BYTE_CNTID_0:
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
default:
|
2020-05-22 18:44:00 +08:00
|
|
|
|
return 0; // modify by liuxueli 20200522
|
|
|
|
|
|
//return -1;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-12 12:18:02 +08:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
return 1;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-22 18:44:00 +08:00
|
|
|
|
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;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|
|
|
|
|
|
return 1;
|
2020-05-12 12:18:02 +08:00
|
|
|
|
}
|
2020-05-22 18:44:00 +08:00
|
|
|
|
|