This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/decoders/glimpse_detector/quic_identify.cpp
2024-08-21 09:38:18 +08:00

238 lines
8.5 KiB
C++

#include <arpa/inet.h>
#include "app_l7_protocol.h"
#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
//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
/**************************************************************************/
/* 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 0xFFA5
#define EXTENSION_COMPRESS_CERT 0x001B
#define EXT_QUIC_PARAM_MAX_IDLE_TIMEOUT 0x01
#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_MAX_FRAME_SIZE 0x20
#define EXT_QUIC_PARAM_INIT_SRC_CONN_ID 0x0F
#define EXT_QUIC_PARAM_USER_AGENT 0x7129
#define EXT_QUIC_PARAM_NOT_YET_SUPPORTED 0x712B
#define EXT_QUIC_PARAM_QUIC_VERSION 0x80004752
#define EXT_QUIC_PARAM_GREASE_LOW4 0x91D24E9B
#define EXT_QUIC_PARAM_GREASE_HIGH4 0xEA666DE7
#define EXTENSION_QUIC_PARAM_UA 0x7129
#define EXTENSION_QUIC_PARAM_VERSION 0x4752
enum _QUIC_VERSION app_identify_get_quic_protocol(int curdir_is_c2s, const unsigned char *payload, const int payload_len)
{
enum _QUIC_VERSION quic_version = QUIC_VERSION_UNKNOWN;
if(payload_len<5)
{
return QUIC_VERSION_UNKNOWN;
}
// Q001~Q043: 0x80 is currently unused, and must be set to 0
// The most significant bit (0x80) of byte 0 (the first byte) is set to 1 for long headers
(payload[0] & 0x80) ? (quic_version = (enum _QUIC_VERSION)ntohl(*(unsigned int *)(payload + 1))) : QUIC_VERSION_UNKNOWN;
if (
(quic_version == GQUIC_VERSION_Q099) ||
(quic_version == PICOQUIC_VERSION_30) ||
(quic_version == PQUIC_VERSION_PROX) ||
(quic_version == GQUIC_VERSION_T099) ||
(quic_version >= GQUIC_VERSION_Q044 && quic_version <= GQUIC_VERSION_Q050) ||
(quic_version >= GQUIC_VERSION_Q051 && quic_version <= GQUIC_VERSION_Q059) ||
(quic_version >= GQUIC_VERSION_T048 && quic_version <= GQUIC_VERSION_T049) ||
(quic_version >= GQUIC_VERSION_T050 && quic_version <= GQUIC_VERSION_T059) ||
(quic_version >= QUANT_VERSION_00 && quic_version <= QUANT_VERSION_FF) ||
(quic_version >= QUIC_GO_VERSION_00 && quic_version <= QUIC_GO_VERSION_FF) ||
(quic_version >= QUICLY_VERSION_00 && quic_version <= QUICLY_VERSION_FF) ||
(quic_version >= MSQUIC_VERSION_00 && quic_version <= MSQUIC_VERSION_0F) ||
(quic_version >= MOZQUIC_VERSION_00 && quic_version <= MOZQUIC_VERSION_0F) ||
(quic_version >= MVFST_VERSION_00 && quic_version <= MVFST_VERSION_0F) ||
(quic_version >= IQUIC_VERSION_I001 && quic_version <= IQUIC_VERSION_I032) ||
(quic_version == IQUIC_VERSION_RFC9000))
{
return quic_version;
}
char public_flags=payload[0];
int used_len = 1;
if(curdir_is_c2s==0 && public_flags & GQUIC_PUBLIC_FLAG_VERSION)
{
return QUIC_VERSION_UNKNOWN;
}
if((!public_flags)&GQUIC_PUBLIC_FLAG_PKT_NUM)
{
if(public_flags&GQUIC_PUBLIC_FLAG_VERSION) //Public Reset Packet
{
return QUIC_VERSION_UNKNOWN;// todo
}
else // Version Negotiation Packet
{
return QUIC_VERSION_UNKNOWN;
}
}
if(public_flags&GQUIC_PUBLIC_FLAG_CID)
{
used_len+=sizeof(unsigned long long); // CID length
}
if(payload_len>=(int)(used_len+sizeof(int)) && public_flags&GQUIC_PUBLIC_FLAG_VERSION && (*(unsigned char *)(payload+used_len)==0x51))
{
quic_version=(enum _QUIC_VERSION)ntohl(*(unsigned int *)(payload+used_len));
used_len+=sizeof(int); // skip version
}
if(quic_version<GQUIC_VERSION_Q001 || quic_version>GQUIC_VERSION_Q043)
{
return QUIC_VERSION_UNKNOWN;
}
return quic_version;
}