본 글은 Computer Networking: a Top Down Approach의 UDP 챕터를 정리한 글입니다.
TCP
와 UDP
의 가장 기본적인 기능은 두 end system을 연결하는 IP 시스템을 두 프로세스의 연결로 확장하는 것이다.
그러한 행위를 바로 멀티플렉싱과 디멀티플렉싱이라고 부른다.
TCP
와 UDP
는 무결성 체크를 위해 에러 감지 필드 또한 제공한다.
UDP
가 하는 기능은 오직 위 두가지 기능 뿐이다.
TCP
는 UDP
와 달리 신뢰성 있는 데이터 전송을 제공하며,
혼잡 제어(congestion control) 또한 가능하다.
혼잡 제어는 어플리케이션을 위한 서비스라기보다 인터넷 전체를 위한 서비스라고 할 수 있고,
TCP
연결이 방대한 양의 트래픽이 라우터와 링크를 마비시키는 것을 방지한다.
이것은 송신 속도를 조절하는 것으로 이뤄지는데,
UDP는 규제되지 않아 마음대로 속도를 높일 수 있다.
전송 계층 프로토콜이 할 수 있는 최소한의 일만 하는 프로토콜
멀티플렉싱/디멀티플렉싱 혹은 간단한 에러체킹 이외에 IP 프로토콜에게 아무 영향도 주지 않는다.
만약 특정 프로그램이 UDP
프로토콜을 사용하면, 해당 프로그램은 IP와 거의 직접적으로 소통한다.
Handshake 과정이 없기 때문에 비연결성(connectionless) 이라 불린다.
UDP
를 사용하는 어플리케이션 레이어 프로토콜의 대표적인 예시이다.
DNS 어플리케이션이 쿼리를 생성하려고 할 때,
DNS 메시지를 만들어 UDP
에게 곧바로 전달한다. 목적지와의 Handshake도 없다.
DNS 어플리케이션은 쿼리의 답변을 기다리게 되는데,
일정시간동안 답변을 받지 못하면 쿼리를 재전송한다.
언제, 어떤 데이터가 보내지는지 어플리케이션 수준에서 제어하기 쉬워짐:
TCP
는 혼잡 제어(congestion control) 기능을 가지고 있고, 목적지에게 송신 segment의 답장을 받기까지 대기하기 때문에, UDP
가 TCP
에 비해 시간적인 측면에서 우위를 가진다.
고로 낮은 딜레이를 요구하고, 데이터 손실에 큰 신경을 쓰지 않는 실시간 어플리케이션에는 TCP
가 적합하지 않다.
연결 생성 작업 없음:
TCP
에는 3way handshake 방식이 적용되어 데이터 통신 이전에 선행 작업이 필요하다. UDP
에는 선행 작업이 전무하며, 연결 생성에 어떠한 딜레이도 산출하지 않는다.연결 상태 없음:
TCP
는 끝단에서 연결 상태를 유지하고, 이 연결 상태는 수신 및 송신 버퍼와 혼잡 제어 파라미터, 시퀀스, ACK 넘버를 포함한다. 이것들은 모두 혼잡 제어와 신뢰성을 제공하기 위한 것들이며, UDP
는 이 정보들을 하나도 필요로 하지 않는다. 그래서 UDP
를 채택한 서버가 TCP
를 채택한 서버보다 더 많은 활성(active) 클라이언트를 지원할 수 있다.패킷 헤더 오버헤드가 작음:
TCP
는 모든 세그먼트에 대략 20바이트 정도의 헤더를 가지지만, UDP
는 고작 8바이트의 헤더를 가진다.많은 중요 어플리케이션 또한 UDP
에서 작동한다.
대표적으로 SNMP
(네트워크 관리)인데, network management 어플리케이션은 네트워크의 체증이 심할 때 주로 작동한다. 그때 신뢰성을 지키며 혼잡 제어된 데이터를 전송하기란 어렵다. 그래서 UDP
를 사용한다.
그리고 앞서 소개된 DNS
는 연결 생성 딜레이를 없애기 위해 UDP
를 사용한다.
요즘은 TCP
와 UDP
가 함께 사용될 때도 있다. 실시간 영상 회의, 스트리밍 서비스가 그렇다. 이런 서비스들의 공통점은 신뢰성 있는 데이터 전송이 필수가 아니라는 것이다. 그리고 TCP
의 혼잡 제어 기능에 굉장히 형편없이 반응한다.
반면에 패킷 손실율이 낮고, UDP
를 사용하기에는 보안적인 문제가 있을 때 스트리밍 서비스에 TCP
가 선호된다.
UDP
를 사용해도 신뢰성을 지키는 방법도 있다. 어플리케이션 자체가 신뢰성을 지키도록 설계되는 것이다. 대표적인 예시가 QUIC
프로토콜이다.
UDP
헤더는 오직 4가지 field만 갖는다. 각 필드의 크기는 2바이트이다.
(2 * 4 = 8바이트)
Length
: 헤더의 크기를 포함한 메시지의 크기를 저장한 값 (단위: 바이트)
Checksum
: segment에 에러가 포함됐는지 확인하기 위해 필요
UDP
segment 뿐만 아니라, IP
헤더에서도 계산되는 fieldsegment가 목적지까지 전달되면서 변조되었는지 확인하기 위한 비트
송신자는 segment 내의 모든 16비트의 합을 1의 보수로 변형하여 Checksum
field에 저장합니다. (더하기 후에 16비트를 넘어서는 값은 잘라냄)
세 개의 16비트
첫번째 비트와 두번째 비트합을 구한다.
두번째 비트와 세번째 비트합을 구한다. (오버플로우는 잘라냄)
최종 결과를 1의 보수처리 (0은 1로, 1은 0으로)
수신자는 segment 내의 모든 16비트의 합을 구함(Checksum
까지 포함)
송신 쪽의 3가지 비트의 합을 1의 보수처리한 것이 Checksum
이므로, 수신 측에서 3가지 비트와 Checksum
을 더하면 모두 비트값을 1로 갖는 16비트가 결과로 나와야 함.
하나라도 비트값을 0으로 가지는 결과가 나온다면 통신 과정에서 변조가 발생한 것.
통신 과정에 포함되는 모든 프로토콜이 에러체킹을 제공하지는 않기 때문
segment가 라우터의 메모리에 보관되는 도중에 비트 변조가 일어날 수도 있기 때문
위 두가지를 고려하여, end-to-end 원칙에 의해 UDP
는 전송 계층에게 에러 체킹 기능을 제공해야함. (end-to-end 원칙의 대표적인 예시)
하지만 UDP
가 에러 체킹을 한다고 에러를 고친다는 생각은 하지 않아야 된다. UDP
가 에러를 발견하면 그저 어플리케이션에게 주의를 줄 뿐이다.
UDP
는 TCP
와 같은 전송 계층 프로토콜이다.
TCP
와 달리 3way handshake가 필요없고, 연결 상태 정보를 필요로 하지 않기 때문에 비연결성이라고 불린다.
TCP
와 다르게 혼잡 제어를 제공하지 않으며, 8비트의 헤더 덕분에 패킷 오버헤드도 적다.
데이터 손실이 치명적이지 않고, 낮은 딜레이가 필요한 시스템에서 주로 채택된다.