본문 바로가기
학교공부/[컴퓨터 네트워크]

[컴퓨터 네트워크] -Transport layer _ Transport layer의 진화

by 윈디개 2025. 6. 2.

 지난 글에서는 TCP의 Congestion control, 즉 혼잡 제어 방식까지 정리했다. Congestion Control의 여러 방식, AIMD, TCP slow start, Congestion Avoidance, TCP CUBIC, TCP ECN 등 살펴보고 TCP와 UDP의 fairness까지 정리해 보았다.

 

 이번 글에서는 Transport layer의 진화 과정에 대해서 알아보려고 한다.


1. Transport layer의 진화

 Transport layer의 대표 프로토콜로, TCP, UDP가 있다. 이들은 지난 40년 동안 transport layer의 주요 프로토콜로 자리잡았다. 그렇지만 다음과 같은 구체적인 시나리오에 대응하기 위해, 다양한 형태로 발전해 왔다. 아래 표를 한 번 살펴보자.

Scenario Challenges
길고 직경이 큰 pipe들 길기 때문에 RTT도 크고, bandwidth도 동시에 크면, in-flight 상태의 패킷 수가 많은 상태를 유지해야 링크를 효율적으로 사용하는 것이다.
Wireless networks(예: 스마트폰을 들고 이동 중에 기지국이 달라진다.) 기지국 사이에 이동 중, 일시적으로 연결이 끊겨 loss가 발생한다. (TCP는 이를 congestion loss라고 판단해 cwnd를 줄이는데, 실제로는 심각한 congestion이 아닌 상황이라 cwnd를 낮출 필요가 없다. 불필요한 성능저하가 발생한다.)
매우 긴 link RTT가 매우 클 것이다.
(TCP는 RTT가 크면 timeout 발생할 확률이 높아지고 timeout이 발생하면 cwnd를 낮춘다. 그렇지만 실제로 congestion한 상태가 아니라 cwnd를 낮출 필요는 없다.)
Data center의 network는 서버들끼리 매우 인접한 상태라 Latency가 매우 짧다. 매우 낮은 Latency(지연시간)을 활용하여 TCP 연결을 미리 열어 놓고 유지하며, 데이터가 필요할 때 빠르게 전송 가능하다.
Backgroud traffic flows(본점-지점을 상시 연결 background에 따로 존재) 상시 연결 backgroun flow는 낮은 우선 순위로 두고, client 요청은 높은 우선순위로 두어야 한다. 

 

위의 표를 보면 알 수 있듯이, Classic TCP는 다양한 네트워크 scenario에 최적화되어 있지 않았다. 따라서 각 상황에 맞춰 새로운 TCP 버전들이 등장했다.

 

예를 들어,  매우 긴 link에서는 RTT가 큰 것을 고려한 더 느린 cwnd 조절 방식이 필요했고, TCP의 설계도 그에 맞춰 발전했다.

 

 이처럼 Transport layer는 하나의 고정된 방식으로는 다양한 네트워크 Scenario를 모두 커버할 수 없어서 최근에는 QUIC 같은 새로운 프로토콜이 등장하고 있다.

 

 QUIC은 HTTP/3에서 사용하는 프로토콜로, transport layer의 UDP 프로토콜을 기반으로 하면서, TCP의 핵심 기능들(reliablility, congestion control)은 상위 계층인 application layer에서 구현하도록 하게 만든 것이다.


2. QUIC

2.1 QUIC의 등장 배경과 특징

 

 기존의 application layer 프로토콜 중 HTTP/2까지는 모두 TCP를 기반으로 동작했다. 간단히 복습하면, HTTP/2는 여러 스트림을 하나의 TCP 연결 안에서 multiplexing하여 전송하지만, 하나의 패킷이라도 손실되면 전체 흐름이 지연되는 HOLBlocking 문제가 존재했다.

 

 예를 들어, 여러 데이터 스트림을 전송할 때 작은 데이터조차 앞선 큰 데이터의 전송이 끝날 때까지 지연될 수 있다. 이를 어느 정도 완화하기 위해 HTTP/2에서는 스트림 간 전송 우선순위를 지정하는 기능이 도입되었다. 하지만, TCP 특성상 하나의 스트림의 패킷 손실이 발생해도 모든 스트림이 영향을 받는 문제가 있었다.

 

 이 문제를 해결하기 위해 등장한 것이 UDP를 사용한 HTTP/3 방식이다. 이 HTTP/3는 QUIC 프로토콜을 기반으로 동작한다.

 

 QUIC은 기본적으로 application layer의 프로토콜이며, UDP 위에서 작동한다. 다음 그림을 통해 정확히 어디서 작동하는지 살펴보자.

 

 

 그림의 왼쪽은 TCP 위에서 작동하는 HTTP/2 방식을, 오른쪽은 UDP 위에서 작동하는 HTTP/3 방식을 나타낸 것이다.

 

QUIC을 기반으로 하는 HTTP/3 방식은 현재 Google 서버나 앱을 포함해 다양한 서비스에서 실제로 사용되고 있다.

 

 먼저 왼쪽의 HTTP/2 방식부터 살펴보면, TCP 위에 Application 계층에 TLS가 존재하고 그 위에 HTTP/2가 있다. 여기서 TLS(Transport Lyaer Security)는 인터넷에서 데이터를 안전하게 주고받기 위해 사용하는 보안 프로토콜로, 다음과 같은 역할을 한다.

  • 암호화(Encryption) : 데이터 암호화해서 제 3자가 내용을 볼 수 없게 만든다.
  • 인증(Authentication) : 통신 상대의 신원을 확인
  • 무결성(Integrity) : 데이터의 무결성 보장

이처럼 TLS는 신뢰성 있는 연결을 전제로 설계된 프로토콜이며, 따라서 신뢰성을 제공하는 TCP 위에서만 동작할 수 있다.
즉, UDP 위에서는 TLS가 직접 동작할 수 없다.

 

 이를 해결하기 위해 등장한 것이 바로 QUIC이다. 오른쪽 그림을 보면, UDP 위에 QUIC이 위치하고, 그 위에서 애플리케이션 계층의 프로토콜인 HTTP/2가 합쳐져 HTTP/3를 이룬다. QUIC은 UDP 위에서 동작하면서, 다음과 같은 역할을 할 수 있다.

  • TLS의 보안 기능 보장(Authentication, Encryption 등)
  • 신뢰성 보장 (손실 복구, 순서 보장 등)
  • 연결 설정(혼잡 제어, 신뢰성)

즉, QUIC은 UDP + TLS + TCP의 핵심 기능을 통합한 프로토콜로, UDP 환경에서도 TCP 수준의 보안과 신뢰성을 제공할 수 있도록 설계된 것이다.

 

2.2 QUIC 연결 설정

 

 QUIC은 TCP와 TLS를 이용하는 HTTP/2에서처럼 연결 설정을 지원한다고 했는데, 실제로는 어떤 절차를 거쳐 연결이 이루어질까?

 

 HTTP/2와 HTTP/3의 연결 설정을 다음 그림을 통해 비교해보자

 

먼저 왼쪽은 HTTP/2에서 TCP와 TLS의 연결 설정 과정이다. 더 자세히 설명하면,

  1. TCP handshake(3-way handshake)를 한 뒤,
  2. TLS handshke를 통해 암호화(Encryption), 무결성(Integrity), 인증(Authentication) 등을 위한 보안 연결을 별도로 설정한다.

즉, HTTP/2는 두 개의 큰 단계로 구성된 연속적인 handshake 과정이 필요하다.

 

그렇다면, HTTP/3에서 사용되는 QUIC은 어떨까?

  1. QUIC은 단 한 번의 handshake만으로 연결 설정이 완료된다.

 그 이유는 UDP는 연결 설정이 따로 필요 없으며, 전송 계층의 기능(TCP 역할)과 보안 계층의 기능(TLS 1.3)을 내부적으로 모두 포함하고 있기 때문이다. 따라서 QUIC에서는 1 RTT 만에 데이터 전송을 시작할 수 있으며, 이 점에서 연결 설정 속도가 매우 빠르다는 것을 알 수 있다.

 

이처럼 연결 설정은 빨라졌지만, 내부적으로는 TLS와 연결 관리, 혼잡 제어까지 통합되어 있기 때문에 QUIC은 실제 구현이 매우 복잡한 프로토콜이다.

 

3.2 QUIC의 실제 동작 과정

 

그럼 QUIC은 실제로 어떤 과정을 거쳐 실행될까? 다음을 한 번 살펴보자.

 

먼저 왼쪽 그림부터 살펴보자. 왼쪽 그림은 TCP를 이용한 HTTP/1.1 버전을 나타낸 것이다. 

 

이 상황에서는 클라이언트가 서버로 GET 요청 3개(GET 1, 2, 3)를 순차적으로 보내는 상황을 가정한다. 이때 다음과 같은 순서로 일이 진행된다/

  1. GET1번이 server측에 정상적으로 잘 도달했다. server는 해당 ACK를 보낸다.
  2. 그 뒤, ACK를 받은 client는 다음 GET 2번을 보낸다.
  3. 이때 server측의 TCP RDT(신뢰성 있는 데이터 전송을 보장하기 위한 모듈)에서 error를 감지했다고 가정하자.(패킷 loss를 감지했다고 가정)
  4. GET 2번에 대한 ACK가 오지 않고 timeout이 발생한다면, client는 GET 3번을 보내지 않고 GET 2번을 retransmission 한다.
  5. 이 과정에서 GET 3번 계속 대기 중인 상태이다.
  6. GET 2번에 대한 ACK를 받은 후에야 비로소 client가 GET 3번을 보낸다.

이처럼 HTTP/1.1은 순차적 전송 기반이기 때문에, 하나의 요청에서 오류가 발생하면 그 이후 요청들이 지연되는 HOL Block 문제가 발생한다.

 

오른쪽 그림을 살펴보자. 오른쪽 그림은 QUIC을 이용한 HTTP/3 버전을 나타낸 것이다.

 

전제는 동일하게 GET 요청 3개를 보내는 상황이며, GET 2번에서 오류가 발생하는 것도 동일하게 가정한다.

  1. GET 2번에 대한 loss가 QUIC RDT에서 감지되었다.
  2. QUIC은 스트림 단위 전송을 지원하기 때문에 클라이언트는 GET 2번의 오류 여부와 상관없이 GET 3번을 전송한다.
  3. server 측에서 데이터를 조립할 때, 만약 GET 2번에 대한 데이터가 도착하지 않았다면, QUIC의 신뢰성 모듈(RDT)이 손실을 감지하고 client로 하여금 GET 2번을 재전송하게 한다.
  4. 이후 GET 2번이 server에 도착하면, 각 요청은 스트림 단위로 개별적으로 조립되어 처리된다.

즉, QUIC은 각 스트림이 독립적으로 동작하기 때문에, 한 스트림에서의 손실이 다른 스트림의 전송에 영향을 주지 않는다.