모든 이야기

가볍게 보내되 책임은 남는다: UDP 데이터그램

UDP는 IP 위에서 포트와 간단한 헤더를 사용해 데이터그램을 주고받는 전송 프로토콜이다. TCP처럼 연결 설정, 순서 복원, 손실 재전송을 자체적으로 제공하지 않는다. 대신 응용이 데이터그램 단위로 통신할 수 있어, 필요에 맞는 전송 정책을 직접 구성하기 쉽다.

음성 데이터그램 중 일부가 손실되거나 순서가 바뀌고 수신 응용이 재생 시점을 기준으로 처리하는 그림

UDP가 제공하지 않는 순서·복구·재생 정책은 응용 또는 상위 프로토콜이 맡는다.

스트림이 아닌 독립적인 전송 단위

UDP 헤더는 출발지 포트, 목적지 포트, 길이, 체크섬으로 이루어진다. 포트는 같은 호스트의 여러 응용을 구별하는 데 쓰인다. 데이터그램은 독립적인 전송 단위이며 UDP가 여러 데이터그램을 하나의 연속적인 바이트 스트림으로 재구성하지 않는다. 수신 버퍼가 작으면 API에 따라 일부 데이터가 잘릴 수 있으므로 충분한 버퍼와 명시적인 길이 처리가 필요하다.

손실, 중복, 순서 뒤바뀜은 응용이 고려해야 한다. UDP 자체의 확인 응답이 없으므로 send가 성공했다고 상대가 받았다고 결론 내릴 수 없다. 체크섬은 전송 중 손상을 검출하기 위한 것이며 악의적인 변조를 막는 인증이나 암호화와는 다르다.

실시간 음성에서는 이미 재생 시점이 지난 오래된 패킷을 늦게 다시 받는 것보다 최신 패킷을 제시간에 받는 편이 중요할 수 있다. 응용은 시퀀스 번호와 타임스탬프를 붙이고 작은 지터 버퍼를 두며, 일부 손실을 은폐하거나 선택적으로 복구할 수 있다. UDP가 음성을 자동으로 부드럽게 재생해 주는 것은 아니다.

보장을 덜 갖춘 것이 항상 더 빠르지는 않다

짧은 질의에서는 연결 설정을 생략하는 장점이 있을 수 있다. 그러나 큰 데이터 전송에서 손실 복구와 혼잡 관리를 나쁘게 구현하면 성능과 공정성이 TCP보다 떨어질 수 있다. UDP를 쓴다는 이유로 네트워크가 감당하지 못할 만큼 계속 보내도 된다는 뜻은 아니다.

큰 데이터그램은 IP 단편화나 경로 MTU 문제에 부딪힐 수 있다. 조각 하나가 유실되면 전체 데이터그램을 재조립하지 못하므로, 응용에서 적절한 전송 크기를 정하는 일이 중요하다. 데이터그램 크기, 처리율, 지연, 손실을 함께 측정해야 한다.

UDP 위에서도 신뢰성과 보안을 구현할 수 있다. QUIC처럼 UDP를 운반 수단으로 쓰면서 자체적인 연결, 손실 복구, 혼잡 제어와 암호화를 제공하는 프로토콜이 대표적이다. 따라서 UDP는 용도가 정해진 빠른 통신의 별명이라기보다, 비교적 작은 기본 보장 위에 필요한 정책을 쌓는 전송 인터페이스로 이해하는 편이 좋다.

데이터그램 기반 프로토콜을 설계할 때는 각 패킷이 독립적으로 해석 가능한지부터 정한다. 시퀀스 번호는 중복과 순서를 구별하고, 타임스탬프는 재생 시점을 판단하며, 요청 식별자는 응답을 원래 질의와 연결하는 데 도움을 준다. 이 정보들은 목적이 다르므로 하나의 숫자가 모든 기능을 대신한다고 생각하면 안 된다. 재전송을 넣는다면 기다리는 시간과 재시도 횟수, 혼잡 상황의 전송 감속도 함께 정해야 한다. 수신자가 없거나 답이 오지 않는 경우를 무한 재전송으로 처리하면 장애를 더 키울 수 있다. 작은 기본 프로토콜의 장점은 정책 선택의 자유에 있고, 그 자유만큼 응용 설계자가 결정해야 하는 부분도 늘어난다.

참고 자료

가볍게 보내되 책임은 남는다: UDP 데이터그램 · ariser