QUIC簡介
QUIC的全稱是 Quick UDP Internet Connection,叫做快速UDP網絡連接配接,是Google提出的一個基于UDP的可靠的安全的傳輸協定。
QUIC的改進
相較于HTTP2+TCP+TLS,QUIC有以下優點:
1、 QUIC減少了TCP+TLS的握手時間
2、 QUIC減少了TCP的隊頭阻塞
3、 QUIC支援連接配接轉移
4、 QUIC支援改進版的擁塞控制
5、 QUIC有着更精确的RTT時間
QUIC封包結構
一個QUIC的基本機關為packet,也就是包。
QUIC頭部
1、 Flags占8個位元組,裡面記錄了封包的類型、ConnectionID的長度、Version的長度、Packet Number的長度。
2、 Connection ID:一個QUIC連接配接對應着一個Connection ID,是一個QUIC 連接配接 的唯一辨別。 QUIC 不用 源IP、源端口、目的IP、目的端口 四元組來為唯一辨別一個連接配接,而是通過一個Connection ID,目的是為了連接配接轉移。
3、 Version : QUIC的版本号
4、 Packet Number: 一個QUIC包的唯一辨別,是遞增的。
QUIC實際資料
QUIC包中的資料是由多個幀組成的。我們先說下幀的結構
1、 Type 中包含幀的類别,比如ack幀、FIN幀等、還有流辨別符、資料偏移量、資料大小的位元組長度。
2、 流辨別符:一個發送請求對應着一個流
3、 流偏移量:目前幀在流中的偏移位置
4、 資料長度: 幀中攜帶資料的位元組大小
5、 接下來就是實際傳輸的資料。
QUIC組成結構
一個發送請求對應着一個流。
一個流中包含多個幀。
一個流可以通過多個包進行傳遞。
QUIC 就是由 包 packet 和 幀 組成的。
一個packet 包中可以同時包含多個幀。幀與幀之間沒有關系。
幀 和 packet 之間沒有什麼關系,packet 隻是用來運載幀的。
QUIC安全連接配接詳解
在閱讀下面流程,需要掌握DH算法的工作流程,不熟悉的可以看下我之前俺寫的一篇文章,HTTPS之TLS1.2連接配接詳解。
QUIC 是 安全的, 其使用DH算法生成對稱密鑰。連接配接如下:
1、用戶端發送Client Hello給伺服器,請求DH生成密鑰的參數
2、伺服器傳回對應的參數和公鑰給參數給用戶端
3、用戶端收到DH參數以及伺服器的公鑰,生成了密鑰,然後将自己公鑰發給伺服器。在此時,用戶端已經可以利用密鑰加密資料進行傳輸了。
4、伺服器收到用戶端的公鑰後,也可以得出對應的密鑰了,可以解密用戶端發來的密文。
從上述流程看出,僅僅1個RTT,用戶端和伺服器就可以生成對稱密鑰,可以安全的進行連接配接了。
QUIC 還有進一步優化,優化到了0RTT。
用戶端可以緩存伺服器的DH參數,這樣的話,用戶端在進行連接配接的時候,就可以生成對應的密鑰,然後将自己的公鑰傳過去。伺服器同樣可以利用用戶端的公鑰生成密鑰,然後解密資料。
0RRT就可以建立安全連接配接,太好了。
QUIC資料傳輸和重傳
QUIC将上層資料包,比如HTTP3資料包,分成多個幀,然後組裝成一個Packet 發送。
每個幀都會有一個定時器,如果在規定時間内收不到對應的ack,就重傳對應的幀,還是通過packet,如果有其他幀一塊,就湊成一個packet,如果沒有,就自己用一個packet。
QUIC解決隊頭阻塞
TCP利用的是滑動端口,端口中的前面的資料不被讀取,後面的資料無法被讀取,這就意味着不同的請求之間存在前後制約關系,進而出現了隊頭阻塞問題。
因為UDP每個請求都對應着一個流,每個流都直接被拆分成幀直接被發送出去,請求與請求之間不存在制約關系。是以不會存在隊頭阻塞問題。
但是流内部之間由于網絡問題,有的時候會出現後面的資料先于前面的資料發送到對方,也會造成後面的資料等待前面的資料,但這是無法避免的事,任何協定都無法避免。QUIC在這方面已經做到最好了。
QUIC 連接配接遷移
假如 手機 從 WiFi 切換到了 手機資料網絡,對應的IP位址會發生改變。
TCP 是利用 源IP位址、源端口、目的IP位址、目的端口 四元組來唯一辨別一個TCP連接配接。伺服器也是通過這個四元組來維護連接配接資訊的,是以更換了IP位址資訊,肯定要重建立立連接配接。
QUIC是不需要建立連接配接的。
因為QUIC是基于UDP,UDP是無連接配接的,QUIC是通過一個Connection ID來辨別一個連接配接,,伺服器也是通過Connection ID來辨別一個QUIC連接配接的資訊。即使切換了網絡,新網絡還可以通過之前的Connection ID來繼續利用之前的連接配接,無需建立連接配接。
QUIC估算RTT
相較于TCP,因為TCP逾時重傳的Seq 和之前的包是一模一樣的,發送方無法判斷是之前發送的包的ack,還是重傳的包的ack,有歧義性。當出現重傳的時候,就會造成RTT的不準确。
QUIC就不一樣了,QUIC每次重傳都會新增對應的Packet Num,RTT完全就是每個包對應的往返時間。
與此同時,QUIC還會統計伺服器收到資料包和傳回ACK的相關時間,也就說會将伺服器處理資料的時間從RTT中減去,更加精确了。
QUIC的RTT判斷是比較準确的。