iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Modern Web

快還要更快,讀作 quick 的下一代傳輸層協定: QUIC系列 第 11

【Day 11】Negotiating Connection ID,建立連線時雙方如何協商 CID?

  • 分享至 

  • xImage
  •  

前言

在經過昨天的反思後,今後討論的方向還是會先著重在協定交互的行為,至於封包觀察可以等後續如果在寫程式做實驗的時候,方便拿來觀察程式的運作有沒有符合預期。

今天要探討的主題是 QUIC 中很重要的 Connection ID,他是如何決定的,雙方協商的過程又是如何進行。

Connection

QUIC connection 可以想成 Client 端與 Server 端共享狀態的一種抽象概念。

一個 connection 始於 Client 與 Server 開始 Handshake 的時候,雙方在 Handshake 的過程會交換金鑰用於後續的加密傳輸,除此之外,在建立連線的過程中也會交換一些可選的 transport parameters

雙方協商 connection ID 時也會使用到 transport parameters,在稍後的介紹會看到。

底下的示意圖可以參考一下,說明為什麼 connection 會是抽象結構

來源

可以看到在前幾天討論的封包格式外,幾個欄位之前組合起來也代表著抽象的意義,像是 Header 的 Connection ID 等其實實際意義就代表的 Connection 的存在,這種抽象的概念要實作會比較方便,可以定義出 Connection, Stream 等 class,方便管理。

協商過程

在昨天的文章有提到,Packet 有分成 Long Header Packet, Short Header Packet,在雙方協商的時候使用 Long Header Packet 的另一個原因就是需要把要協商的 Connection ID 擺在 Header 的欄位中。

Long Header Packet 中與 Connection ID 的欄位有

  • Destination Connection ID Length
    • 描述 Destination Connection ID 長度
  • Destonation Connection ID
    • 存放實際的 Destination Connection ID(最多 160 bits)
  • Source Connection ID Length
    • 描述 Source Connection ID 長度
  • Source Connection ID
    • 存放實際的 Source Connection ID(最多 160 bits)

一開始 Client 端會生成自己的 Connection ID 放在 Source Connection ID 欄位,這時候因為還沒有跟 Server 溝通過,所以 Destination Connection ID 還不清楚,隨機生成一個放到 Initial Packet 的 Destination Connection ID 欄位。

隨機生成的 Destination Connection ID 長度至少要 8 bytes,在還沒有跟 Server 端取得連線之前都必須要使用這個隨機生成的 DCID 填入 Destination Connection ID 欄位。

這個隨機生成的 DCID 其實是有用的,不僅僅只是因為還沒有獲得 Server 的 Connection ID 而已,在 Initial Packet 也使用這個 DCID 進行所謂的 packet protection,這個在後面的章節會介紹到,簡單來說就是 QUIC 除了 Payload 的加密外,對於 Packet 的 Header 也會進行一定的保護。

對於 Source Connection ID 的思考

Client 傳送的 Source Connection ID 對 Server 來說必須要填入 Destination Connection ID,這應該滿直觀的,但一開始名詞很多的情況下有時候會混淆整個流程,一開始 Client 傳送 SCID 給 Server,Server 接受後傳填入回傳封包的 Destination Connection ID 欄位,並且把 Server 端生成的 Connection ID 填入 Source Connection ID 欄位。

當 Client 首次收到 Server Initial 或者 Retry packet,就必須要把封包的 Destination Connection ID 欄位改成 Server 傳過來的 Source Connection ID。(對於 Client 來說,Server 的 Source 代表 Client 的 Destination)

自此 Server 往後的 Destination Connection ID 也必須要使用從 Client Initial packet 傳來的 Connection ID,除非收到 NEW_CONNECTION_ID frame,如果後續又收到 Client 傳來的 Initial packet 包含不同的 Source Connection ID 則必須要直接丟棄。

結語

如果對交換 Connection ID 過程感興趣的讀者,可以根據前幾天介紹 wireshark 的流程觀察,會發現 Client 的確一開始會生成一個隨機的 DCID,之後收到 Server 的回應後就會把 DCID 改成 Server 的 SCID。

今天主要介紹了一開始建立連線時雙方交換 Connection ID 的過程,明後天我們會來探討如何認證 Connection ID,因為在 Long Header Packet 中的 ID 欄位都是以明碼傳輸,QUIC 利用 transport parameter 來驗證雙方的 Connection ID 有沒有在過程中被人更改,那麼明天見!


上一篇
【Day 10】淺談 QUIC Handshake 流程 (四) - 怎麼利用 wireshark 去對照 RFC + 筆者的段落反思
下一篇
【Day 12】Authenticating Connection IDs,QUIC 在握手時如何驗證 CID
系列文
快還要更快,讀作 quick 的下一代傳輸層協定: QUIC23
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言