昨天的介紹中我們提到了 QUIC 另一個很重要的機制 - Connection Migration, 也延伸出了 Connection ID 的用途,QUIC 藉由 Connection ID 來紀錄 Client 的狀態,即使 Client 的 IP 變了,也可以透過 Connection Migration 機制避免重複建立連線。
今天我們會介紹一個為達成 Connection Migration 實現的必要機制 - Path Validation。
Path Validation 主要目的是在連線雙方發生 Connection Migration 時,用以驗證更改後地址的可達性(reachability)。
簡單的說,Path Validation 就是測試送出去的封包對面是否能成功接收,還能確保 Connection Migration 後的新地址並非偽造的。
Path Validation 並不會驗證對方是否有能力傳送封包給自己,僅驗證我方的封包對方能成功接受。
Path Validation 流程由一個端點發起,該端點發送 PATH_CHALLENGE frame 包含一些 unpredictable payload(實作彈性很大),只發送一次 PATH_CHALLENGE frame 可能有機會丟失,所以 RFC 這邊建議實作上可以發送多個 PATH_CHALLENGE 避免丟失的風險,前提是每個 PATH_CHALLENGE 都必須在不同的 packet 中。
傳送 PATH_CHALLENGE frame 時至少要把封包大小填充到 1200 bytes,這點是為了因應前幾天介紹的防止放大攻擊機制。
在接收到 PATH_CHALLENGE frame 之後,接收方必須要把 frame 中包含的 unpredictable payload 取出,並且放入 PATH_RESPONSE frame 中回傳。除非受到擁塞控制的限制,不然 PATH_RESPONSE 必須立刻回傳。
同樣的,PATH_RESPONSE frame 也必須要填充到 1200 bytes,一個 PATH_CHALLENGE 只能回傳一個 PATH_RESPONSE,不能發送多個 response 對應單個 challenge。
當發起 PATH_CHALLENGE frame,並收到包含原先 payload 的 PATH_RESPONSE frame,一定要有相同的 payload,如果只是收到對 PATH_CHALLENGE 的 ACK 是無法完成驗證的,因為 ACK 有被惡意攻擊者偽造的可能性。
只有主動發起驗證的端點放棄驗證時,才會是驗證失敗,實務上會設定一個 timer 專門來計算超時,只要超時就定義該路徑無法抵達,關於 timer 的時間設定有很多彈性空間,RFC 中也有很多補充的觀點可以參考。
有很多原因可能會導致失敗,像是對方的位置真的無法抵達,又或者在驗證期間對方 Connection Migration 到另一個新的位置,導致舊的 path 失效。