ossl-guide-quic-introduction
名稱
ossl-guide-quic-introduction - OpenSSL 指南:OpenSSL 中的 QUIC 簡介
簡介
此頁面將簡介一些基本的 QUIC 概念和背景,以及如何在 OpenSSL 中使用它。它假設您對 UDP/IP 和 socket 有基本的了解。它還假設您熟悉一些 OpenSSL 和 TLS 基礎知識(請參閱 ossl-guide-libraries-introduction(7) 和 ossl-guide-tls-introduction(7))。
什麼是 QUIC?
QUIC 是一個通用協定,讓應用程式能夠透過網路安全地通訊。它在 RFC9000 中定義(請參閱 https://datatracker.ietf.org/doc/rfc9000/)。QUIC 整合 TLS 協定的部分內容以建立連線,但獨立保護封包。它提供與 TLS 類似的安全保證,例如機密性、完整性和驗證(請參閱 ossl-guide-tls-introduction(7))。
QUIC 提供許多優點
- 多重串流
-
它支援多重通訊串流(請參閱下方的「QUIC 串流」),讓建構在 QUIC 上的應用程式協定能夠為用戶端和伺服器之間的通訊建立任意數量的位元組串流。這讓應用程式協定能夠避免資料封包等待另一個封包傳送而延誤的問題(通常稱為「隊首封鎖」)。它也讓應用程式能夠開啟額外的邏輯串流,而不需要像開啟額外的 TLS/TCP 連線時那樣,在用戶端和伺服器之間進行封包的往返交換。
- HTTP/3
-
由於 QUIC 是 HTTP/3 的基礎,因此支援 QUIC 也讓應用程式能夠使用適當的第三方程式庫使用 HTTP/3。
- 快速連線啟動
-
未來版本的 OpenSSL 將提供對 0-RTT 連線啟動的支援,讓連線可以啟動至伺服器,並在沒有任何等待時間的情況下傳輸應用程式資料。這類似於 TLS 1.3 的 0-RTT 功能,但同時避免了開啟 TCP socket 所需的往返時間;因此,它類似於 TLS 1.3 0-RTT 和 TCP 快速開啟的組合。
- 連線遷移
-
未來版本的 OpenSSL 將提供對連線遷移的支援,讓連線可以在 IP 位址變更時無縫存活。
- 基於資料報的用例
-
未來版本的 OpenSSL 將提供對 QUIC 資料報擴充功能的支援,讓單一連線同時支援 TLS 和 DTLS 型式的用例。
- 實作為應用程式函式庫
-
由於大多數 QUIC 實作(包括 OpenSSL 的實作)是實作為應用程式函式庫,而不是作業系統,因此應用程式可以在不需要等待作業系統更新部署的情況下,獲得 QUIC 的好處。QUIC 協定的未來演進和增強功能,可以像更新應用程式一樣快速提供,而不需要依賴作業系統更新的節奏。
- 在單一 UDP socket 上多工
-
由於 QUIC 是基於 UDP,因此可以在與其他一些基於 UDP 的協定(例如 RTP)相同的 UDP socket 上,多工 QUIC 連線。
QUIC 時間基礎事件
OpenSSL 中 TLS 實作和 QUIC 實作之間的一個主要差異,在於時間的處理方式。QUIC 協定要求定期執行各種動作,無論是否正在傳輸或接收應用程式資料。
OpenSSL 引進了一個新函式 SSL_handle_events(3),它將自動處理任何必須處理的未完成時間基礎事件。或者,呼叫任何 I/O 函式,例如 SSL_read_ex(3) 或 SSL_write_ex(3),也會處理這些事件。還有 SSL_get_event_timeout(3),它會告訴應用程式在 SSL_handle_events(3)(或任何 I/O 函式)必須被呼叫之前,剩餘的時間量。
幸運的是,一個不會讓 QUIC 連線閒置,並定期呼叫 I/O 函式的阻擋式應用程式,通常不需要擔心這一點。但是,如果您正在開發一個非阻擋式應用程式,或一個可能會讓 QUIC 連線閒置一段時間的應用程式,那麼您需要安排呼叫這些函式。
OpenSSL 提供一個可選的「執行緒協助模式」,它會自動建立一個背景執行緒,並會定期以執行緒安全的方式呼叫 SSL_handle_events(3)。這提供了一個簡單的方法,讓應用程式可以滿足 QUIC 對基於時間事件的要求,而無需實作特殊邏輯來達成此目的。
QUIC 和 TLS
QUIC 在其實作中重複使用 TLS 協定的部分。特別是 TLS 交握也存在於 QUIC 中。TLS 交握訊息會封裝在 QUIC 協定訊息中,以便將它們傳送給對等方。一旦 TLS 交握完成,所有應用程式資料都會完全使用 QUIC 協定訊息傳送,而不會使用 TLS - 儘管在某些情況下仍可能會傳送一些 TLS 交握訊息。
QUIC 和 TLS 之間的這種關係表示,OpenSSL 中許多適用於 TLS 連線的 API 函式也適用於 QUIC 連線,而且應用程式可以用完全相同的方式使用它們。有些函式根本不適用於 QUIC,而其他函式則有不同的語意。您應該參閱每個函式的文件頁面,以取得有關它如何套用於 QUIC 的資訊。通常,如果手冊頁面中未提到 QUIC,則這些函式同時適用於 TLS 和 QUIC。
QUIC 串流
QUIC 引入了「串流」的概念。串流提供了一個可靠的機制,可以在端點之間傳送和接收應用程式資料。傳輸的位元組保證會按照傳送順序接收,而不會遺失資料或重新排序位元組。TLS 應用程式實際上每一個 TLS 連線都有一個雙向串流可用。QUIC 應用程式可以為每個連線使用多個單向或雙向串流。
在 OpenSSL 中,SSL 物件用於表示連線和串流。QUIC 應用程式會建立一個初始的 SSL 物件來表示連線(稱為連線 SSL 物件)。一旦連線完成,就可以建立其他 SSL 物件來表示串流(稱為串流 SSL 物件)。除非另有設定,否則「預設」串流也會與連線 SSL 物件關聯,因此您仍然可以寫入資料並從中讀取資料。有些 OpenSSL API 函式只能與連線 SSL 物件一起使用,而有些只能與串流 SSL 物件一起使用。請查看每個函式的文件,以確認在任何特定情況下可以使用哪種類型的 SSL 物件。具有附加預設串流的連線 SSL 物件可以用於需要連線 SSL 物件或需要串流 SSL 物件的環境中。
SOCKET 與封鎖
TLS 假設其底層傳輸層協定為「串流」型語意(通常透過使用 TCP 來達成)。然而,QUIC 則透過使用 UDP 假設「資料報」型語意。使用 QUIC 的 OpenSSL 應用程式負責建立一個 BIO 來表示底層傳輸層。此 BIO 必須支援資料報,通常為 BIO_s_datagram(3),但也有其他 BIO 選項可用。請參閱 bio(7) 以了解 OpenSSL 的 BIO 概念簡介。
OpenSSL TLS 應用程式與 OpenSSL QUIC 應用程式之間的一個顯著差異在於封鎖的實作方式。在 TLS 中,如果您的應用程式預期封鎖行為,則您會將底層 socket 設定為封鎖。相反地,如果您的應用程式想要非封鎖行為,則將底層 socket 設定為非封鎖。
對於 OpenSSL QUIC 應用程式,底層 socket 必須始終設定為非封鎖。然而,預設情況下,SSL 物件仍會以封鎖模式運作。因此,從應用程式的角度來看,呼叫 SSL_read_ex(3)、SSL_write_ex(3) 等函式和其他 I/O 函式仍會封鎖。OpenSSL 本身會為 QUIC 提供封鎖功能,而非 socket。如果需要非封鎖行為,則應用程式必須呼叫 SSL_set_blocking_mode(3)。
進一步閱讀
請參閱 ossl-guide-quic-client-block(7),以了解如何應用這些概念來撰寫一個簡單的封鎖 QUIC 用戶端。
另請參閱
ossl-guide-introduction(7)、ossl-guide-libraries-introduction(7)、ossl-guide-libssl-introduction(7)、ossl-guide-tls-introduction(7)、ossl-guide-tls-client-block(7)、ossl-guide-quic-client-block(7)、bio(7)
版權
版權所有 2023 The OpenSSL Project Authors。保留所有權利。
根據 Apache 授權條款 2.0 版(「授權條款」)授權。您不得使用此檔案,除非符合授權條款。您可以在原始程式碼散佈中的 LICENSE 檔案中取得一份副本,或在 https://www.openssl.org/source/license.html 取得。