/*
 * quic.h
 *
 *  Created on: 2019-4-4
 *      Author: root
 */

#ifndef _GQUIC_H_
#define _GQUIC_H_

#define QUIC_INTEREST_KEY		    (1<<QUIC_INTEREST_KEY_MASK)
#define QUIC_CLIENT_HELLO		    (1<<QUIC_CLIENT_HELLO_MASK)
#define QUIC_SERVER_HELLO		    (1<<QUIC_SERVER_HELLO_MASK)
#define QUIC_CACHED_CERT		    (1<<QUIC_CACHED_CERT_MASK)
#define QUIC_COMM_CERT		        (1<<QUIC_COMM_CERT_MASK)
#define QUIC_CERT_CHAIN		        (1<<QUIC_CERT_CHAIN_MASK)
#define QUIC_APPLICATION_DATA	    (1<<QUIC_APPLICATION_DATA_MASK)
#define QUIC_USEING_VERSION			(1<<QUIC_USEING_VERSION_MASK)
#define QUIC_NEGOTIATION_VERSION	(1<<QUIC_NEGOTIATION_VERSION_MASK)
#define QUIC_REJECTION			    (1<<QUIC_REJECTION_MASK)


enum quic_interested_region
{
	QUIC_INTEREST_KEY_MASK = 0,
	QUIC_CLIENT_HELLO_MASK,
	QUIC_SERVER_HELLO_MASK,
	QUIC_CACHED_CERT_MASK,
	QUIC_COMM_CERT_MASK,
	QUIC_CERT_CHAIN_MASK,
	QUIC_APPLICATION_DATA_MASK,
	QUIC_USEING_VERSION_MASK,
	QUIC_NEGOTIATION_VERSION_MASK,
	QUIC_REJECTION_MASK
};

typedef struct _quic_tlv
{
    unsigned int type;
	unsigned int length;
	void	*value;
}quic_tlv_t;

#define	MAX_CONNECT_ID_LEN	18

struct _quic_public_header
{
	unsigned char public_flags;
	unsigned char is_reset;
	unsigned char is_sepcial_packet;	// special Packets
	unsigned char is_version_negotiation;
	unsigned char server_CID_len;
	unsigned char client_CID_len;
	unsigned char negotiation_version_num;
	unsigned int quic_version;
	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
	unsigned int *negotiation_version_list;
};
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_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_info
{
	struct _quic_stream *rejection;
	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);
//ret: 0: not quic, >0: quic version
unsigned int quic_protocol_identify(struct streaminfo *a_stream, void *a_packet, char *out_sni, int *out_sni_len, char *out_ua, int *out_ua_len);

#endif /* SRC_GQUIC_H_ */
