/*
 * quic_process.h
 *
 *  Created on: 2019��4��2��
 *      Author: root
 */

#ifndef SRC_GQUIC_GQUIC_PROCESS_H_
#define SRC_GQUIC_GQUIC_PROCESS_H_

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

#include "gquic.h"

//#define VERSION_LEN  4
//#define VER_Q046                   

#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

//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


//https://datatracker.ietf.org/doc/html/draft-ietf-quic-transport-27#section-12.4
//IQIIC  Frame type (GQUIC_Q046 is iQUIC 17)
#define	IQUIC_FRAME_PADDING				0x00
#define	IQUIC_FRAME_PING				0x01
#define	IQUIC_FRAME_ACK_HEX02			0x02
#define	IQUIC_FRAME_ACK_HEX03			0x03
#define	IQUIC_FRAME_RESET_STREAM		0x04
#define	IQUIC_FRAME_STOP_SENDING		0x05
#define	IQUIC_FRAME_CRYPTO				0x06
#define	IQUIC_FRAME_NEW_TOKEN			0x07
#define	IQUIC_FRAME_STREAM_HEX08		0x08
#define	IQUIC_FRAME_STREAM_HEX09		0x09
#define	IQUIC_FRAME_STREAM_HEX0A		0x0A
#define	IQUIC_FRAME_STREAM_HEX0B		0x0B
#define	IQUIC_FRAME_STREAM_HEX0C		0x0C
#define	IQUIC_FRAME_STREAM_HEX0D		0x0D
#define	IQUIC_FRAME_STREAM_HEX0E		0x0E
#define	IQUIC_FRAME_STREAM_HEX0F		0x0F
#define	IQUIC_FRAME_MAX_DATA			0x10
#define	IQUIC_FRAME_MAX_STREAM_DATA		0x11
#define	IQUIC_FRAME_MAX_STREAMS_HEX12	0x12
#define	IQUIC_FRAME_MAX_STREAMS_HEX13	0x13
#define	IQUIC_FRAME_DATA_BLOCKED		0x14
#define	IQUIC_FRAME_STREAM_DATA_BLOCKED	0x15
#define	IQUIC_FRAME_STREAMS_BLOCKED_HEX16	0x16
#define	IQUIC_FRAME_STREAMS_BLOCKED_HEX17	0x17
#define	IQUIC_FRAME_NEW_CONNECTION_ID		0x18
#define	IQUIC_FRAME_RETIRE_CONNECTION_ID	0x19
#define	IQUIC_FRAME_PATH_CHALLENGE		0x1A
#define	IQUIC_FRAME_PATH_RESPONSE		0x1B	
#define	IQUIC_FRAME_CONNECTION_CLOSE_HEX1C	0x1C
#define	IQUIC_FRAME_CONNECTION_CLOSE_HEX1D	0x1D


/**************************************************************************/
/*                      Message tag                                       */
/**************************************************************************/
#define CHLO 0x43484C4F
#define SHLO 0x53484C4F
#define REJ  0x52454A00
#define PRST 0x50525354


/**************************************************************************/
/*                      Tag                                               */
/**************************************************************************/
#define TAG_PAD  0x50414400
#define TAG_SNI  0x534E4900
#define TAG_VER  0x56455200
#define TAG_CCS  0x43435300
#define TAG_UAID 0x55414944
#define TAG_PDMD 0x50444d44
#define TAG_STK  0x53544b00
#define TAG_SNO  0x534E4F00
#define TAG_PROF 0x50524F46
#define TAG_SCFG 0x53434647
#define TAG_RREJ 0x5252454A
#define TAG_CRT  0x435254FF
#define TAG_AEAD 0x41454144
#define TAG_SCID 0x53434944
#define TAG_PUBS 0x50554253
#define TAG_KEXS 0x4B455853
#define TAG_OBIT 0x4F424954
#define TAG_EXPY 0x45585059
#define TAG_NONC 0x4E4F4E43
#define TAG_MSPC 0x4D535043
#define TAG_TCID 0x54434944
#define TAG_SRBF 0x53524246
#define TAG_ICSL 0x4943534C
#define TAG_SCLS 0x53434C53
#define TAG_COPT 0x434F5054
#define TAG_CCRT 0x43435254
#define TAG_IRTT 0x49525454
#define TAG_CFCW 0x43464357
#define TAG_SFCW 0x53464357
#define TAG_CETV 0x43455456
#define TAG_XLCT 0x584C4354
#define TAG_NONP 0x4E4F4E50
#define TAG_CSCT 0x43534354
#define TAG_CTIM 0x4354494D
#define TAG_MIDS 0x4D494453
#define TAG_FHOL 0x46484F4C
#define TAG_STTL 0x5354544C
#define TAG_SMHL 0x534D484C
#define TAG_TBKP 0x54424B50

/* Public Reset Tag */
#define TAG_RNON 0x524E4F4E
#define TAG_RSEQ 0x52534551
#define TAG_CADR 0x43414452

#define	EXTENSION_SERVER_NAME	0x0000
#define	EXTENSION_SUPPORT_GROUP	0x000A
#define	EXTENSION_APP_PROT_NEGO	0x0010	//application layer protocol negotiation
#define	EXTENSION_SIG_ALGORITHM	0x000D
#define	EXTENSION_KEY_SHARE		0x0033
#define	EXTENSION_PSK_EXCHANGE	0x002D
#define	EXTENSION_SUPP_SSL_VER	0x002B
#define	EXTENSION_QUIC_PARAM_TLS_33	0x0039  /* draft-ietf-quic-tls-33 */
#define	EXTENSION_QUIC_PARAM_TLS_13	0xFFA5  /* 0xffa5 draft-ietf-quic-tls-13 */
#define	EXTENSION_COMPRESS_CERT	0x001B
#define	EXTENTION_UNKNOWN		0x4469

//  https://www.iana.org/assignments/quic/quic.xhtml
#define	EXT_QUIC_PARAM_ORIGINAL_DST_CONN_ID		0x00
#define	EXT_QUIC_PARAM_MAX_IDLE_TIMEOUT			0x01
#define	EXT_QUIC_PARAM_STATELESS_RST_TOKEN		0x02
#define	EXT_QUIC_PARAM_MAX_UDP_PAYLOAD			0x03
#define	EXT_QUIC_PARAM_MAX_INIT_DATA			0x04
#define	EXT_QUIC_PARAM_MAX_STREAM_BIDI_LOCAL	0x05
#define	EXT_QUIC_PARAM_MAX_STREAM_BIDI_REMOTE	0x06
#define	EXT_QUIC_PARAM_MAX_STREAM_UNI			0x07
#define	EXT_QUIC_PARAM_MAX_STREAMS_BIDI			0x08
#define	EXT_QUIC_PARAM_MAX_STREAMS_UNI			0x09
#define	EXT_QUIC_PARAM_ACK_DELAY_EXPONENT		0x0A
#define	EXT_QUIC_PARAM_MAX_ACK_DELAY			0x0B
#define	EXT_QUIC_PARAM_DISABLE_ACTIVE_MIGRATION	0x0C
#define	EXT_QUIC_PARAM_PREFERRED_ADDRESS		0x0D
#define	EXT_QUIC_PARAM_ACTIVE_CONN_ID_LINIT		0x0E
#define	EXT_QUIC_PARAM_INIT_SRC_CONN_ID			0x0F
#define	EXT_QUIC_PARAM_RETRY_SRC_CONN_ID		0x10
#define	EXT_QUIC_PARAM_MAX_DATAGRAM_FRAME_SIZE	0x20
#define	EXT_QUIC_PARAM_INIT_RTT					0x7127
#define	EXT_QUIC_PARAM_GOOGLE_CONN_OPTIONS		0x7128
#define	EXT_QUIC_PARAM_USER_AGENT				0x7129 // 2021-10-20 deprecated
#define	EXT_QUIC_PARAM_QUIC_VERSION				0x4752

//https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
enum _QUIC_VERSION
{
	QUIC_VERSION_UNKNOWN=0,
	//NetApp
	QUANT_VERSION_00=0x45474700,
	QUANT_VERSION_FF=0x454747FF,

	//Private Octopus
	PICOQUIC_VERSION_30=0x50435130,
	
	//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=0x51303232,
	GQUIC_VERSION_Q023=0x51303233,
	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, 
	GQUIC_VERSION_Q049=0x51303439,

    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 QUIC with TLS 48 - 49 (T048 - T049)
	GQUIC_VERSION_T048=0x54303438,
	GQUIC_VERSION_T049=0x54303439,
	
	//Google QUIC with TLS 50 - 59 (T050 - T059)
	GQUIC_VERSION_T050=0x54303530,
	GQUIC_VERSION_T051=0x54303531,
	GQUIC_VERSION_T052=0x54303532,
	GQUIC_VERSION_T053=0x54303533,
	GQUIC_VERSION_T054=0x54303534,
	GQUIC_VERSION_T055=0x54303535,
	GQUIC_VERSION_T056=0x54303536,
	GQUIC_VERSION_T057=0x54303537,
	GQUIC_VERSION_T058=0x54303538,
	GQUIC_VERSION_T059=0x54303539,

	//Google QUIC with TLS 99 (T099)
	GQUIC_VERSION_T099=0x54303939,
	
	//Google Proxied QUIC
	PQUIC_VERSION_PROX=0x50524f58,

	//quic-go
	QUIC_GO_VERSION_00=0x51474F00,
	QUIC_GO_VERSION_FF=0x51474FFF,

	//quicly
	QUICLY_VERSION_00=0x91c17000,
	QUICLY_VERSION_FF=0x91c170FF,
	
	//Microsoft
	MSQUIC_VERSION_00=0xabcd0000,
	MSQUIC_VERSION_0F=0xabcd000F,

	//Mozilla
	MOZQUIC_VERSION_00=0xf123f0c0,
	MOZQUIC_VERSION_0F=0xf123f0cF,

	//Facebook
	MVFST_VERSION_00=0xfaceb000,
	MVFST_VERSION_01=0xfaceb001,
	MVFST_VERSION_02=0xfaceb002,
	MVFST_VERSION_03=0xfaceb003,
	MVFST_VERSION_04=0xfaceb004,
	MVFST_VERSION_05=0xfaceb005,
	MVFST_VERSION_06=0xfaceb006,
	MVFST_VERSION_07=0xfaceb007,
	MVFST_VERSION_08=0xfaceb008,
	MVFST_VERSION_09=0xfaceb009,
	MVFST_VERSION_0A=0xfaceb00A,
	MVFST_VERSION_0B=0xfaceb00B,
	MVFST_VERSION_0C=0xfaceb00C,
	MVFST_VERSION_0D=0xfaceb00D,
	MVFST_VERSION_0E=0xfaceb00E,
	MVFST_VERSION_0F=0xfaceb00F,
	
	//IETF
	IQUIC_VERSION_RFC9000=0x00000001,
	IQUIC_VERSION_I001=0xFF000001,
	IQUIC_VERSION_I002=0xFF000002,
	IQUIC_VERSION_I003=0xFF000003,
	IQUIC_VERSION_I004=0xFF000004,
	IQUIC_VERSION_I005=0xFF000005,
	IQUIC_VERSION_I006=0xFF000006,
	IQUIC_VERSION_I007=0xFF000007,
	IQUIC_VERSION_I008=0xFF000008,
	IQUIC_VERSION_I009=0xFF000009,
	IQUIC_VERSION_I010=0xFF00000A,
	IQUIC_VERSION_I011=0xFF00000B,
	IQUIC_VERSION_I012=0xFF00000C,
	IQUIC_VERSION_I013=0xFF00000D,
	IQUIC_VERSION_I014=0xFF00000E,
	IQUIC_VERSION_I015=0xFF00000F,
	IQUIC_VERSION_I016=0xFF000010,
	IQUIC_VERSION_I017=0xFF000011,
	IQUIC_VERSION_I018=0xFF000012,
	IQUIC_VERSION_I019=0xFF000013,
	IQUIC_VERSION_I020=0xFF000014,
	IQUIC_VERSION_I021=0xFF000015,
	IQUIC_VERSION_I022=0xFF000016,
	IQUIC_VERSION_I023=0xFF000017,
	IQUIC_VERSION_I024=0xFF000018,
	IQUIC_VERSION_I025=0xFF000019,
	IQUIC_VERSION_I026=0xFF00001A,
	IQUIC_VERSION_I027=0xFF00001B,
	IQUIC_VERSION_I028=0xFF00001C,
	IQUIC_VERSION_I029=0xFF00001D,
	IQUIC_VERSION_I030=0xFF00001E,
	IQUIC_VERSION_I031=0xFF00001F,
	IQUIC_VERSION_I032=0xFF000020
};

struct _quic_context
{
	int is_quic;
	int is_decrypt;
	int cb_version;
	int link_state;
	int call_business;
	void *business_pme;
	struct _quic_info quic_info;
};

int quic_process(struct streaminfo *pstream, struct _quic_context* _context, int thread_seq, void* a_packet);

int quic_init_stream(void **pme, int thread_seq);  // **pme=(struct _quic_context* )
void quic_release_stream(void **pme, int thread_seq);
enum _QUIC_VERSION is_quic_protocol(struct streaminfo *pstream, struct _quic_context* _context, char *payload, int payload_len, int *used_len);


struct _gquic_reset_public_header
{
	unsigned char  public_flags;
	unsigned long long connection_id;
	unsigned int tag;
};

struct _gquic_ack_frame_header
{
	unsigned long long largest_acked;
	unsigned short largest_acked_delta_time;
	unsigned int tag;
};

char quic_callPlugins(struct streaminfo *pstream, struct _quic_context *_context, void *buff, int buff_len, enum quic_interested_region region_mask, void *a_packet);

#endif

