QUIC的那些事 包型別及格式

2021-09-09 01:56:29 字數 4070 閱讀 1989

目錄

報文頭特殊報文

版本協商報文

public reset報文

普通報文(regular packet)

幀包(frame packet)

fec包(fec packet)

參考資料

quic 的 packet 除了個別報文比如 public_reset 和 chlo,所有報文頭部都是經過認證的,報文 body 都是經過加密的。這樣只要對 quic 報文任何修改,接收端都能夠及時發現,有效地降低了安全風險。

如圖 1所示,紅色部分是 stream frame 的報文頭部,有認證。綠色部分是報文內容,全部經過加密。

quic報文分為特殊報文和普通報文。特殊報文又分為兩類:版本協商報文(version negotiation packets)及公共重置報文(public reset packets)。普通報文也分為兩類:幀報文及fec(forward error correction)報文。

quic報文的大小需要滿足路徑mtu的大小以避免被分片。當前quic在ipv6下的最大報文長度為1350,ipv4下的最大報文長度為1370.

quic報文都有乙個公共的頭部,大小在2-19位元組之間,格式如圖 2所示:

其中,圖 2中的長度是以bit為單位,如connection id的0,8,32,64,單位均為bit.

第一位元組為:public  flags

public flag的8位如下所示,左邊為高位,右邊為低位

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

如果bit0被置上(0x01 = public_flag_version = 0x01),該字段的含義取決於報文是客戶端還是服務端傳送。如果是客戶端傳送,這一位被置上表示quic version欄位不為空,且quic version欄位被填充為客戶端的quic版本資訊。在客戶端收到服務端同意建立該版本的連線報文抵達之前,客戶端傳送的所有報文的這一位必須都要被設定。如果服務端同意建立該版本的連線,那麼這一位不用設定。如果這一位被服務端置上,那麼表示該報文是版本協商報文(version negotiation packet)。

如果bit1被置上(0x02 = public_flag_reset),表明該報文是公共重置報文(public reset packet)

bit2、bit3兩位表示報文中的connection id的長度。直至協商另外乙個值之前,在所有的報文中,這兩位必須設定被設定為相同(客戶端可能請求更少的資料,所以connectid的長度需要變化)

0x0c(bit3及bit2均為1)表示connection id長度是8位元組

0x08(bit3位1,bit2為0)表示connection id長度是4位元組

0x04(bit3位0,bit2為1)表示connection id長度是1位元組

0x00(bit3及bit2均為0)表示無connection id

bit4、bit5兩位表示每個資料報中存在的資料報編號的位元組數。對於幀資料,這兩位才使用,對於public reset報文及version negotiation報文,這兩位必須為0

0x30(bit5及bit4均為1)表示:包序號是6個位元組

0x20(bit5為1,bit4為0)表示:包序號是4個位元組

0x10(bit5為0,bit4為1)表示:包序號是2個位元組

0x00(bit5及bit4均為0)表示:包序號是1個位元組

bit6:預留給多路徑使用

bit7:未使用,必須為0

connection id:客戶端隨機選擇的最大長度為64位的無符號整數。但是,長度可以協商。

quic version:quic協議的版本號,32位的可選字段。如果public flag & flag_version != 0,這個字段必填。客戶端設定public flag中的bit0為1,並且填寫期望的版本號。如果客戶端期望的版本號服務端不支援,服務端設定public flag中的bit0為1,並且在該字段中列出服務端支援的協議版本(0或者多個),並且該字段後不能有任何報文。

packet number:長度取決於public flag中bit4及bit5兩位的值,最大長度6位元組。傳送端在每個普通報文中設定packet number。傳送端傳送的第乙個包的序列號是1,隨後的資料報中的序列號的都大於前乙個包中的序列號。

public flags的解析流程如圖3所示:

版本協商報文(version negotiation packet)只由服務端傳送。版本協議報文以1位元組的public flag及8位元組的connection id開始。必須設定public_flag_version且標識connection id長度為8位元組,最後面就是服務端支援的協議版本(4位元組)。

public reset報文以1位元組的public flag及8位元組的connection id開始。必須設定public_flag_reset且標識connection id長度為8位元組,剩餘的部分是quic tag。

tag value map包含如下的tag-values:

rnon (public reset nonce proof):64位的無符號整數,必填

rseq (rejected packet number) :64位的無符號整數,必填

普通的報文被驗證(authenticated)且被加密。公有頭被驗證但是沒有加密,從private flags欄位開始的報文被加密。普通的報文包含aead(authenticated encryption and associated data)報文。普通報文必須被解密,並且密文被解密後,明文以private header開始。

普通報文中私有頭格式如圖 6所示:

private flags解析

當bit0被置為1時(0x01 = flag_entropy): 對於資料報,表示該包包含1位熵;對於fec(forward error correction)包,表示包含受保護包熵的異或。

當bit1被置為1時(0x02 = flag_fec_group):表示是否有fec 字段(forward error correction)

當bit2被置為1時(0x04 = flag_fec):表示是fec包

fec(fec group number offset):可選字段,8位的無符號整數,是相對值。

quic幀資料報由幀填充,通過frame type確定到底是何種資料。

除了私有頭外,幀包有一系列的基於型別的幀資料的負載,通用的幀包的格式如圖 7所示:

fec包(flag_fec標誌被置為1)的負載只包含位於fec組中的每個資料報的空填充負載的xor值。每個fec包的flag_fec_group標誌也必須被置為1。格式如圖8所示

BGP的訊息型別以及格式

bgp是建立在tcp之上的協議,tcp埠號179 1 open 開啟訊息 2 keepalive 存活訊息 3 update 更新訊息 4 notification 報錯訊息 bgp的所有訊息都會以該頭開始 maker 16位元組 全為1,標識bgp報文邊界 length 2位元組 bgp包全長,長...

npm發布包的那些事

正確的發包步驟 不夠清楚?上圖 npm err need auth auth and email requiredfor publishingnpm err need auth you need to authorize this machine usingnpm adduser錯誤。npm err...

Charles抓包的那些事

前言 作為移動端開發人員用的最多的抓包工具就是charles,但是我近幾年一直做pc端的前端開發工作,感覺chrome的devtools已經滿足了日常的工作需求 對於charles的使用也很少。最近開始做一些webview的開發,對於灰度環境,線上環境的bug還是需要用到charles的,所以這篇文...