TCP의 헤더구조
TCP (Transmission Control Protocol)는 전송의 신뢰성과 흐름 제어, 혼잡 제어 등의 역할을 맡고 있는 프로토콜이기 때문에, TCP 헤더에도 이러한 기능을 위한 여러 가지 값이 담겨 있다. 즉, 이 헤더를 보면 개괄적인 TCP의 기능들을 쉽게 훑어볼 수 있다.
이제 그림에 표기된 순서대로 각 필드가 어떤 정보를 담고 있는지 살펴보자.
1. 발신지/목적지 포트 주소
해당 필드들은 각각 16 비트를 할당받는다. 이때 출발지와 목적지의 주소를 판별하기 위해서는 IP 주소와 포트 번호가 필요하다. IP 주소는 당연히 한 계층 밑인 네트워크 계층에 있는 IP의 헤더에 담기기 때문에, TCP 헤더에는 IP 주소를 나타내는 필드가 없고 포트를 나타내는 필드만 존재한다.
2. Sqeunce number
시퀀스 번호는 바이트 단위로 구분되어 순서화되는 번호로, 이를 통해 TCP는 신뢰성 및 흐름제어 기능을 제공한다. 또한 수신자는 쪼개진 세그먼트의 순서를 파악하여 올바른 순서로 데이터를 재조립할 수 있게 된다.
최대 32 bit이므로 최대 4 byte (2^32) 크기의 송신 데이터에, 순서화된 일련번호를 붙일 수 있다.
송신자가 최초로 데이터를 전송할 때는 이 번호를 랜덤 한 수로 초기화하며 이후 자신이 보낼 데이터의 1 byte 당 시퀀스 번호를 1씩 증가시키며 데이터의 순서를 표현한다. 최대값( 4,294,967,296 )이후에는 다시 0부터 시작한다.
3. Acknoledge Number
정리하면, 승인 번호는 다음에 보내줘야 할 데이터의 시작점을 의미한다.
4. 헤더 길이 필드 (Header length, HLEN)
해당 필드는 TCP 세그먼트가 시작하는 위치를 기준으로 데이터의 시작 위치를 나타내므로 TCP 헤더의 크기가 된다.
표기할 땐 32-bits 워드(word) 단위를 사용하는데, 이는 32 bit 시스템에서 1 word = 4 bytes 임을 의미한다. 즉, 해당 필드 값에 4를 곱하면 세그먼트에서 헤더를 제외한 실제 데이터의 시작 위치를 알 수 있다. 예를 들어, 헤더 길이 필드 값이 5라면, 5 * 4 = 20 bytes가 헤더의 길이이며, 데이터는 21번째 byte부터 시작된다는 것이다.
이 필드에 할당된 4 bits로 표현할 수 있는 값의 범위는 0000 ~ 1111, 즉 0 ~ 15 word 이므로 기본적으로 0 ~ 60 bytes의 오프셋까지 표현할 수 있다. 하지만 옵션 필드를 제외한 나머지 필드는 필수로 존재해야 하기 때문에 최소 값은 20 bytes, 즉 5 word로 고정되어 있다.
5. 예약 (Reserved)
미래를 위해 예약된 필드로, 모두 0으로 채워져야 한다.
6. Flags
이건 특히 내용이 많고 다룰 것도 많아서 별도의 소제목으로 옮겨 설명하겠다.
7. Window Size
해당 필드는 한 번에 전송할 수 있는 데이터의 양을 의미하는 값을 담는다. 65535 (2^16) 만큼의 값을 표현할 수 있고, 단위는 바이트이므로, 윈도의 최대 크기는 64 KB라는 말이 된다.
만약 전송하는 데이터의 양이 수신자의 버퍼 용량을 초과하여 수신에 실패한다면 해당 필드 값을 0으로 지정한다. 이 경우, 송신자는 데이터를 전송해선 안된다.
8. Checksum
TCP 세그먼트에 포함되는 프로토콜 헤더와 데이터 모두에 대한 변형 오류를 검출하기 위해 사용한다. IP 프로토콜에서 사용하는 오류 검출 알고리즘을 사용한다.
9. Urgent Pointer (긴급 포인터)
긴급 데이터를 처리하기 위한 필드로, 예약 필드의 URG 플래그 비트가 지정된 경우에만 유효하다. 이 필드를 사용해 송신자는 급히 처리해야 하는 데이터를 전송할 수 있다.
예를 들어, 순서 코드가 2000이고 Urgent Pointer가 100인 패킷을 전송한다면 순서 번호 2000 ~ 2099번의 데이터는 긴급 데이터로 전송되고, 2100번 이후로는 정상 데이터로 전송되는 식이다.
TCP Flags
TCP Flag는 그림의 8개 필드와 NS 필드를 추가하여 총 9 개의 비트 플래그로 이루어져 있다.
각 플래그는 현재 세그먼트의 속성을 나타낸다. 기존에는 6 개만을 사용했지만, 혼잡 제어 기능 향상을 위해 예약(Reserved) 필드를 사용하여 NS, CWR, ECE 플래그를 추가하였다.
각 플래그의 의미는 다음과 같다.
필드 | 의미 |
NS | ECN에서 사용하는 CWR, ECE 필드가 실수나 악의적으로 은폐되는 것을 방지하기 위해 RFC-3450에서 추가된 필드 |
CWR | 이미 ECE 플래그를 받아서, 전송하는 세그먼트 윈도우의 크기를 줄였음을 의미함. |
ECE | ECN Echo 플래그. 해당 플래그가 1이고, SYN 플래그도 1이면 ECN을 사용하겠다고 상대방에게 알리는 것. SYN 플래그가 0이라면 네트워크가 혼잡하니 세그먼트 윈도우의 크기를 줄여달라는 요청을 의미함 |
URG | Urgent Pointer(긴급 포인터) 필드에 값이 채워져 있음을 알리는 플래그. 해당 플래그가 가리키는 긴급한 데이터는 우선순위로 처리된다. |
ACK | Acknowledgement Number (승인 번호) 필드에 값이 채워져 있음을 알리는 플래그. 해당 플래그가 0이라면 승인 번호 필드 자체가 무시된다. |
PSH | Push 플래그. 수신 측에게 이 데이터를 최대한 빠르게 응용 프로그램에게 전달하라는 플래그. 해당 플래그가 0이라면 수신 측은 자신의 버퍼가 다 채워질 때까지 기다린다. 해당 플래그가 1이라면 이 세그먼트 이후에 더 이상 연결된 세그먼트가 없음을 의미한다. |
RST | Reset 플래그. 이미 연결이 확립되어 ESTABLISHED 상태인 상대방에게 연결을 강제로 리셋해달라는 요청. |
SYN | Synchronize 플래그. 상대방과 연결을 생성할 때, 시퀀스 번호의 동기화를 맞추기 위한 세그먼트임을 의미함. 해당 플래그가 1이면 TCP 연결 요청을 의미함 해당 플래그가 0이면 TCP 연결 요청에 응답했음을 의미함 |
FIN | Finish 플래그. 상대방과 연결을 종료하고 싶다는 요청인 세그먼트임을 의미함. |
(기존의 예약 필드를 사용하여 새롭게 추가된 NS, CWR, ECE 플래그는 네트워크의 명시적 혼잡 통보(Explicit Congestion, Notification, ECN)을 위한 플래그다.)
TCP 연결방식 3-way Handshaking
- SYN
- 연결을 시작하는 첫 번째 단계로, 클라이언트가 서버로 SYN(Synchronize Sequence Numbers) 패킷을 보낸다.
- SYN 패킷에는 클라이언트가 데이터를 보낼 때 사용할 시퀀스 번호가 포함되어 있다.
- SYN-ACK
- 서버는 클라이언트의 SYN 요청을 받고, SYN과 ACK(Acknowldege)을 결합한 패킷을 클라이언트에게 보낸다.
- ACK
- 클라이언트는 서버의 SYN-ACK 패킷을 받고, 서버의 시퀀스 번호를 확인하는 ACK 패킷을 서버에게 보낸다.
- 클라이언트가 서버의 초기 시퀀스 번호를 받았으며, 이제 양방향 통신이 가능해졌음을 의미한다.
TCP 해제방식 4-way Handshaking
- FIN
- 연결을 종료하고자 하는 호스트(클라이언트 or 서버)는 FIN 플래그가 설정된 패킷을 상대방에게 보낸다.
- 이는 해당 호스트가 더 이상 보낼 데이터가 없음을 의미한다.
- ACK
- 수신 호스트는 FIN 패킷을 받고, ACK 패킷을 보내 이를 확인한다.
- 이때, 수신 호스트는 아직 전송하지 않은 데이터를 모두 보낼 때까지 연결을 유지할 수 있다.
- FIN
- 수신 호스트가 모든 데이터를 전송하고 나서, 두 번째 FIN 패킷을 초기에 FIN을 보낸 호스트에게 전송한다.
- ACK
- 연결을 시작한 호스트가 마지막 FIN 패킷에 대해 ACK을 보낸다.
- 이후, 양쪽 모두 해당 연결을 종료한다.
TCP 재전송과 타임아웃
TCP 재전송은 서버와 클라이언트 간 통신 중 어느 한쪽에 패킷이 도착하지 못할 경우 다시 패킷을 보내는 것을 의미한다. 타임 아웃은 TCP 재전송을 구현하는 방식으로, '타이머가 만료되기 전에 패킷이 도착했는가?'를 기준으로 재전송 여부를 결정하는 것이다.
송신자 패킷 소실
- 송신자가 패킷을 보냈지만 중간에 유실되어 수신 측에 도달하지 못한 경우
- 수신자는 패킷이 도착하지 않았으니 ACK를 보내지 않기 때문에 송신자의 타이머만 만료된다.
ACK 패킷 소실
- 수신자가 송신자의 패킷에 대한 ACK 응답을 보냈지만 송신 측에 도달하지 못한 경우
- 이 때도 송신자의 타이머만 만료된다.
이른 타임아웃(Early Timeout)
- 송신자가 패킷을 보냈고 수신자도 응답으로 ACK을 보냈지만 네트워크 지연으로 인해 송신자의 Timer가 만료된 후 ACK가 도착한 경우.
RTO와 RTT
위 3 가지 상황의 공통점은 'Timeout 시간 안에 ACK를 받지 못했다'는 것이다. 이를 통해 볼 수 있는 TCP 재전송의 중요한 점은 최선의 Timeout 시간을 정의하는 것이다. Timeout 시간이 지나치게 짧으면 재전송 패킷의 낭비가 발생하고, 지나치게 길면 패킷 손상 시 대기 시간이 너무 길어진다. 이를 적절히 다루는 특정한 기준으로 사용하고자 만들어진 개념이 RTO (Retransmission Timeout)이다.
RTO는 RTT에 따라 변하는데, RTT (Round Trip Time)는 호스트 간 송신에 대한 응답을 받기까지 걸리는 시간을 의미한다.
Triple-Duplicate ACK
UDP의 헤더구조
UDP (User Datagram Protocol) 헤더 구조는 TCP 헤더 구조보다 훨씬 간결하다.
일단 발신지와 목적지 포트 주소가 각각 16 bits 이다.
Length는 16 bits 필드로, UDP 헤더 길이와 캡슐화된 데이터가 모두 bytes 형태로 저장되어 있다. 해당 필드가 가질 수 있는 최솟값은 헤더 자체 크기인 8 bytes이다.
Checksum 또한 16 bits로, 주로 헤더와 데이터의 에러 검출에 사용한다. 해당 필드는 IPv4에서는 사용하지 않으면 0으로 맞추는 선택적 요소지만 IPv6부터는 의무적으로 사용하도록 바뀌었다.
체크섬 필드에서 TCP와 UDP의 차이점
UDP Checksum | TCP Checksum | |
필수 여부 | IPv6에서 필수 (IPv4에선 사용하지 않을 시, 0) |
모든 사용처에서 필수 |
구성 요소 | UDP 헤더와 데이터 + 출발지와 목적지 IP 주소와 프로토콜, 그리고 UDP 길이를 포함하는 pseudo 헤더 |
TCP 헤더, 데이터, 그리고 TCP 전체 세그먼트를 포함하는 pseudo 헤더 |
정리하면, 체크섬 방식은 두 프로토콜 모두에서 네트워크 간 데이터 무결성을 보장하기 위해 사용한다.
차이점은 TCP는 신뢰성 있는 정보 전달을 위해 이를 의무적으로 수행하는 반면, UDP 체크섬은 빠른 전송을 위해 이를 선택적으로 사용한다.
참고로 체크섬 계산 방식은 다음과 같다.
1. TCP와 UDP 각각 pseudo 헤더를 준비한다.
> pseudo 헤더는 실제 전송 시에 포함하진 않고, 오직 체크섬 계산에만 사용된다.
> pseudo 헤더는 출발지/목적지 IP 주소와 프로토콜, 그리고 TCP, UDP 각각의 헤더와 데이터 길이를 포함한다.
2. 체크섬 계산 전에 체크섬 필드는 0으로 초기화된다.
3. pseudo 헤더와 헤더, 그리고 데이터를 포함한 전체 패킷을 16 bits 세그먼트 단위로 쪼갠다.
4. 이들을 모두 더한 뒤 오버플로우가 발생하면 오버플로우 값('캐리')을 떼어낸 값에 다시 더한다.
5. 최종 합계에 1의 보수를 취하여 전송할 세그먼트의 checksum 필드에 저장한다.
6. 수신자는 수신한 세그먼트의 sum을 계산하여 함께 전송된 checksum과 더해 16 bits가 모두 0인지 확인한다.
이렇게 열심히 구한 체크섬 또한 때때로 틀릴 수 있다.
전송 중 데이터 변경이 일어났는데 그 데이터의 payload가 작을 경우 우연히 체크섬과 맞아떨어질 수도 있고, 체크섬 필드가 전송 중에 변형되었을 수도 있다.
결국 이를 보완하기 위해 추가적인 에러 탐지나 교정 기술 또한 필요하다.
UDP의 통신 방식
TCP가 연결 지향적이고 신뢰성 있는 데이터 전송을 지원하는 반면, UDP는 연결이 없는(connectionless) 프로토콜로 설계되었다. 이는 UDP가 데이터 교환을 위해 TCP처럼 복잡한 3-way나 4-way 핸드셰이킹 과정을 거치지 않는다는 것이다.
UDP에서 데이터를 전송하는 과정은 다음과 같다.
- 송신 : 송신자는 UDP 헤더와 데이터를 포함하는 데이터그램을 생성하고, 이를 네트워크로 보낸다
- 수신
- 수신자는 네트워크에서 데이터그램을 받는다.
- UDP는 수신된 데이터그램의 체크섬을 검사하여 데이터 오류를 감지한다.
- 하지만 데이터가 손실되거나 순서가 바뀌어도 UDP 자체는 이를 복구하거나 재정렬하지 않는다.
이처럼 UDP는 데이터의 재전송 요청, 데이터 순서 보장, 흐름 제어 등을 제공하지 않기 때문에, UDP를 사용하는 애플리케이션 자체에서 이러한 기능을 구현해야 한다.
참고 출처
'리팩토링' 카테고리의 다른 글
리팩토링 6주차. OSI 계층별 프로토콜 특징 (2) (1) | 2024.07.22 |
---|---|
리팩토링 5주차. OSI 계층 별 프로토콜 특징 (1) (1) | 2024.07.15 |
리팩토링 4주차. OSI 계층별 네트워크 장비 특징 (2) | 2024.07.02 |
리팩토링 2주차. OSI 7계층 (1) | 2024.06.10 |
리팩토링 1주차. 제로 트러스트(Zero Trust)에 대해 (1) | 2024.06.03 |