QUIC
QUIC 연혁
- QUIC은 TCP를 대체하는 범용 목적의 전송 계층 통신 프로토콜로, 구글의 짐 로스킨드가 처음 설계하였고, 2012년 구현 및 적용되었으며, 2013년 공개 발표되었다.
- 국제 인터넷 표준화 기구에 기술되었고, 2021년 5월 IETF RFC9000(+RFC9001/9002/8989)으로 정식 표준화되었다.
- 이미 구글 크롬에서부터 구글 서버에 이르는 모든 연결의 절반 이상에 사용되고있으며, 크롬/MS 엣지/모질라 파이어폭스/사파리에서 지원함
- 관련 사이트 : https://quicwg.org/
QUIC & HTTP/3 출현 배경
- 화석화/고착화(Ossification) 탈피
- 네트워크 중간 영역과 관련된 기술들은 업그레이드되는 속도가 느리기 때문에, 새로운 기능이 생기거나 변경 사항이 추가되면 잘못된 정보로 인식하거나 허용하지 않는 경우가 발생할 수 있다. 이를 고착화라고 하며, 고착화을 방지하기 위해 네트워크 중간 영역에서 많은 것을 볼 수 없도록 통신을 암호화를 한다.
- TCP의 현대 사회에 어울리지 않는 동작
- slow start : 시작 속도가 느리다.
- 한 번 에러가 발생하면 속도가 느려지는 폭이 크다.
- Head of Line blocking : 한 줄로 데이터를 전송하는데, 이때 sequence number에 따라 데이터를 전달하므로 앞의 데이터가 손실되면 뒤가 전달되지 못하고 쌓이게 된다.
QUIC의 특장점
UDP based NEW Transport Protocol
-
UDP를 기반으로 하여 새롭게 만들어진 전송 프로토콜로, TCP와 유사하게 에러 검출 및 복구를 할 수 있다.
![](https://velog.velcdn.com/images/eunna/post/a52aa20a-8807-4206-b592-230917cbe474/image.png)
-
QUIC은 UDP 위에 새로운 계층을 추가함으로써 신뢰성을 제공함. 추가된 계층은 TCP에 존재하는 패킷 재전송, 혼잡 제어, 속도 조정, 우선순위 제어 및 다른 기능들을 제공한다.
- UDP는 데이터 전송의 신뢰성을 보장하지 않는다.
-
QUIC은 (TCP와 같은) 범용의 전송 프로토콜로, 다른 애플리케이션 프로토콜을 그 위에서 사용할 수 있다.
- 첫 애플리케이션 계층 프로토콜은 HTTP/3(h3)이다.
Connection based Transport
QUIC Connection (= 연결)
- QUIC 연결은 두 QUIC 엔드포인트 사이의 연결이다,
- QUIC의 연결 설정은 버전 협상, 암호화, 전송 핸드쉐이크로 구성되어 있으므로 연결 설정의 지연시간을 줄여준다.
- QUIC의 연결을 통해 실제 데이터를 보내려면 하나 이상의 스트림을 만들어서 사용해야 한다.
QUIC Connection ID
- 각 연결은 연결 식별자나 연결 ID를 가지므로 이를 통해 연결을 식별한다. 따라서 클라이언트와 서버의 IP 주소가 바뀌더라도 연결 ID가 동일하다면 연결이 유지될 수 있다.
- 엔드포인트가 자유롭게 연결 ID를 선택하며, 각 엔드포인트는 엔드포인트의 피어가 사용할 연결 ID를 선택한다.
- 연결 ID의 주요 기능은 하위 프로토콜 계층(UDP, IP 혹은 그 아래 계층)에서 주소가 변경되더라도 QUIC 연결의 패킷이 잘못된 엔드포인트로 전달되지 않도록 보장하는 것이다.
Stream based Transport
- QUIC은 하나의 연결로 다수의 병렬 스트림을 전송하며, 스트림 간에 영향을 주지 않고 데이터를 동시에 전송한다.
- 스트림은 62비트 정수의 스트림 ID 식별자로 구분한다.
- 스트림은 순서대로 전달되고 신뢰할 수 있지만 서로 다른 스트림은 순서 없이 전달될 수 있다.(상호 독립적이다)
- QUIC은 연결과 스트림 모두에서 흐름 제어를 제공한다.
- QUIC을 사용하는 상위 계층을 통해서 스트림에 대한 우선 순위를 요청받아, 이를 토대로 정보 교환을 할 수 있다.
Secure Communication
- QUIC은 TLS 1.3을 사용해서 암호화 및 보안을 수행한다.
- TCP와 TLS는 서로 독립적이지만(TCP 연결을 뚫은 다음에 TLS 연결을 뚫음), QUIC과 TLS 1.3은 연결 설정 과정을 동시에 수행하여 프로토콜 지연을 줄일 수 있다.
- TLS를 기본으로 사용하므로, 웹 사용자가 기대하고 원하는 HTTPS의 모든 보안 속성을 지원한다.
Reduced {Signaling} Latency
- QUIC은 0-RTT, 1-RTT 핸드쉐이크를 제공하는데 이는 새로운 연결을 협상하고 설정하는데 걸리는 시간을 줄여준다. (연결에 필요한 메시지를 보내는 시간이 줄어들어 전송에 필요한 시간이 줄어듦)
- RTT(Round Trip Time) : 패킷 왕복 시간, 패킷망(인터넷) 상에서 송신지부터 목적지 호스트까지 패킷이 왕복하는데 걸리는 시간, 패킷이 목적지에 도달한 후 해당 패킷에 대한 응답이 출발지로 다시 돌아오기까지의 시간. 1-RTT면 한 번 보내고 다시 받을 때까지 걸리는 시간을 의미, 0-RTT면 보내고 응답을 받는 시간이 존재하지 않음을 의미)
- QUIC은 추가로 더 많은 데이터를 허용하는 "이른 데이터 (early data; 연결 설정을 하면서 보내는 데이터)”를 처음부터 지원한다.
- 재연결 시, 연결에 필요한 시간을 줄이기 위해 이전에 서버에 연결했던 클라이언트는 해당 연결의 특정 파라미터를 캐시한 뒤 이어서 서버와 0-RTT 연결을 설정할 수 있다.
HTTP/3는 QUIC 위에서 돌아가는 HTTP이다.
HTTP/3
HTTPS:// URLs
- HTTP/3는 HTTPS:// URL을 사용한다.
- 새로운 URL 체계를 만들지 않고, 기존 체계를 유지한다.
- TLS 필수화에 따른 초기 연결 경우
- 이전에 방문한 적이 없는 HTTPS:// URL에 대한 새로운 첫 연결은 아마도 TCP를 통해 수행될 것이다. (추가로 QUIC을 통 한병렬연결 시도가 있을 수 있음)
- 최신 클라이언트와 서버는 아마도 첫 핸드쉐이크에서 HTTP/2를 협상할 것이다. 연결이 설정되고 클라이언트의 HTTP 요청에 서버가 응답할 때 서버는 HTTP/3의 지원과 선호도에 관해 클라이언트에게 알려줄 수 있다.
Alt-svc (Alternative Service)
- 초기 연결이 HTTP/2나 HTTP/1을 사용하더라도 서버는 다시 연결해서 HTTP/3를 시도할 수 있다고 클라이언트에게 알려줄 수 있다.
- 이는 같은 호스트일 수도 있고 요청한 내용을 제공하는 방법을 아는 다른 호스트일 수도 있다.
- 예를 들어, 서버가 Alt-Svc: h3=“:50781"를 응답에 포함 하면, 50781 UDP 포트에서 HTTP/3를 사용할 수 있음을 나타내는 의미로 Client에 전달된다.
- 그 다음 클라이언트는 해당 목적지에 QUIC 연결을 설정하려고 시도하고 연결이 성공하면 초기 HTTP 버전 대신 이러한 출처와 계속해서 통신할 수 있다.
HTTP/3 Frame
- HTTP/3는 연결 설정 후, 한정된 타입의 프레임을 송수신한다.
- HTTP/3의 주요 프레임
- HEADERS : 압축된 HTTP 헤더를 보낸다.
- DATA : 바이너리 데이터 콘텐츠를 보낸다.
- GOAWAY : 연결을 종료한다.
- QPACK Headers
- HEADERS 프레임은 HTTP/2의 HPACK과 유사한 QPACK에 의해 압축된다.
우선순위 제어
- HTTP/3 스트림 프레임 중에서는 PRIORITY 프레임이 있으며, 이 프레임은 HTTP/2에서 동작한 방식과 유사하게 스트림의 우선순위와 의존성을 설정하는 데 사용된다.
- PRIORITY 프레임은 특정 스트림이 다른 스트림에 의존하도록 설정할 수 있고, 해당 스트림에 "가중치"를 설정할 수 있다.
- 종속된 스트림은 의존하는 스트림이 모두 닫혔을 때만 리소스가 할당받아야 하고 아니면 진행될 수 없다.(부모가 존재하면, 부모 먼저 전달)
- 스트림 가중치는 1부터 256 사이의 값을 가지며 같은 부모를 가진 스트림은 반드시 가중치에 따라 리소스를 할당받아야 한다.
서버 푸시
- HTTP/3 서버 푸시는 HTTP/2와 유사하지만 다른 메커니즘을 사용한다.
- 서버 푸시는 클라이언트가 보낸 적이 없는 요청에 대한 효율적인 응답이다.
- 서버 푸시는 클라이언트 쪽에서 서버 푸시에 동의했을 때만 발생할 수 있다. HTTP/3에서는 클라이언트가 최대 푸시 스트림의 ID가 무엇인지 서버에게 알려주어 클라이언트가 얼마나 많은 푸시를 받을 지를 제한하며, 이 제한을 초과하면 연결 오류가 발생할 수 있다.
- 서버는 PUSH_PROMISE를 통해 서버 푸시 전 클라이언트에게 미리 서버 푸시에 대해 알려준다.
- 클라이언트는 서버에 CANCEL_PUSH 프레임을 보내서 푸시된 개별 스트림을 언제든 취소할 수 있다.
HTTP/2 vs HTTP/3
HTTP/2와 HTTP/3의 유사점
- 스트림을 제공한다.
- 서버 푸시를 지원한다.
- 헤더 압축을 제공한다. (QPACK과 HPACK은 설계상 유사함)
- 스트림을 이용해서 하나의 연결을 통해 멀티플랙싱을 제공한다.
- 스트림에 우선순위를 정할 수 있다.
HTTP/2와 HTTP/3의 차이점
- QUIC의 0-RTT 핸드쉐이크 덕에 HTTP/3에서는 이른 데이터 지원이 더 잘 동작한다.
- HTTP/3는 QUIC 덕에 TCP + TLS보다 훨씬 더 빠른 핸드쉐이크를 제공한다.
- HTTP/3에는 안전하지 않거나 암호화되지 않은 버전이 없다. 인터넷에서 드물기는 하지만 HTTP/2는 HTTPS 없이 구현하고 사용할 수 있다.
- HTTP/2가 ALPN 확장을 이용하여 즉시 TLS 핸드쉐이크 협상을 완료할 수 있는 반면, HTTP/3는 QUIC을 사용하므로 클라이언트에 이 사실을 알리기 위해 Alt-Svc: 헤더 응답이 먼저 있어야 한다.
- ALPN(Application Layer Protocol Negotiation) : TLS handshake 이후에 application layer의 프로토콜과 버전을 결정하기 위한 기능. 클라이언트가 HTTP/1.1과 2를 지원한다는 것을 ALPN에게 전달하고 서버가 ALPN과 HTTP/2를 지원한다면, 클라이언트가 h2를 적었을 때 handshake 이후 HTTP/2로 통신이 시작된다
QUIC 이슈 및 발전 방향
Non Socket API
- QUIC에는 표준 API가 없다.
- QUIC에서는 기존 라이브러리 구현체 중 하나를 선택하고 그 API를 따라야 한다. 이는 애플리케이션을 어떤 부분에서 하나의 라이브러리에 "락인(locked in)”시키는 것이다. 다른 라이브러리로 바꾼다는 것은 다른 API를 뜻하므로 많은 작업이 필요할 것이다.
Kernel & Code Optimization
- 구글과 페이스북은 QUIC의 대규모 배포가 TLS에서 HTTP/2로 서비스할 때보다 같은 트래픽 기준으로 거의 2배의 CPU가 필요하다고 보고하였다.
- 현재 업계와 학계에서의 QUIC 프로토콜 성능 개선을 위한 연구가 활발하게 논의중이다.