[ACSA 교육#8] TCP 헤더

지난 포스팅에서는 Layer 3 네트워크 계층에서의 IPv4 헤더에 대해서 알아보았습니다.

오늘은 전송계층, Layer 4에서 볼 수 있는 TCP와 UDP에 대해서 알아볼까 합니다.

3-Way Handshake

먼저 TCP는 애플리케이션 데이터를 처리하기 전에 먼저 목적지까지 안정적으로 데어터가 전달될 수 있도록 제어 가능한 연결을 설정합니다. 아래 그림을 살펴보면 Host B의 HTTP 애플리케이션은 일종의 발송 대기함(Outbox)에서 Host A로 전송되어야 할 데이터를 갖고 있습니다.

I-ITT P 
TCP 
Port 80 
ACK 
Host A 
Source port: 36890 
Destination port: 80 
H 17 p 
Hey TCP, 
DATA 
get this data to Host A 
SYN ACK2SEQ8 
One moment please. 
I must setup a connection 
SEQI SYN 
SEQ 2ACK9 ACK 
TCP 
Reliable, flow-controlled connection is established 
Host B

HTTP는 “TCP! 이 데이터를 Host A로 보내줘야 해!”라고 합니다. 그럼 TCP는 “네, 알겠습니다. 하지만 먼저 Host A와 연결을 맺어야 데이터가 신뢰되고 제어 가능한 방식으로 전송될 수 있습니다.” 라고 답합니다.

TCP 헤더에는 시퀀스(SEQ) 번호, 승인(ACK) 번호, 그리고 동기화(SYN) 플래그 및 승인(ACK)플래그 등 4개의 기본 필드가 있습니다. Host B는 TCP 패킷을 생성하는 것으로 시작합니다. 이 패킷은 데이터를 전달하지 않고 Host A에게 “연결을 맺어야 한다”라는 신호만 보내게 됩니다.

  1. 그림에서 보시는 것과 같이 Host B는 SEQ = 1을 설정하고 SYN 플래그를 올립니다. (이진수 1로 설정)
  2. Host A는 이를 수신하고 “이 패킷은 SYN플래그가 설정된채로 Host B로부터 왔다. Host B가 나와 연결을 맺기를 원한다.”라는 것을 알게 됩니다.
    Host A는 Host B에게 SEQ =1을 수신했다는 것을 알려줘야 하고 다음 SEQ = 2가 오기를 기다립니다. 이를 위해서 Host A는 ACK = 2가 포함하여 SYN 플래그와 ACK 플래그 모두 표시된 채로  패킷을 전송합니다. Host A와 Host B는 각각 독립적인 컴퓨터이기 때문에, Host B가 SEQ = 1로 태그했지만, Host A는 패킷에 SEQ = 8로 태그합니다. 즉, Host A는 “패킷 번호 8(SEQ=8)을 사용하여 당신의 패킷 번호 1(SEQ=1)의 수신을 승인합니다.“라고 말하게 됩니다.
  3. Host B는 이 패킷을 수신하고,  “다음 SEQ=2를 기다리고 있군요. 그럼, 당신의 패킷 번호 8의 수신을 확인했다는 표시로 여기에.. 패킷 번호 2를 사용합니다. 다음 패킷 번호 9를 기다릴게요.” 라고 응답합니다. 여기에서 보시는 것처럼 ACK플래그가 표시되는 것을 확인할 수 있습니다.

여기서 바로 안정적이고 제어 가능한 연결(Reliable and flow-controlled connection)이 맺어지게 됩니다.

호스트가 다른 호스트로부터 일련의 패킷을 성공적으로 수신하고 승인하게 되면 이제 TCP는 애플리케이션에 대한 데이터 전송을 시작할 준비가 된 것입니다. HTTP는 특정 포트를 사용하여 정보(데이터)를 전달합니다. 이 그림에서는 목적지 포트 번호 80, 출발지 포트 번호는 Host B에서 랜덤하게 생성된 36890로 선택합니다.

Sequence Number

TCP는 한 번에 전송할 수 없는 매우 큰 파일을 전송해달라는 요청을 받기도 합니다. 이럴 때 Host B의 TCP 프로세스는 큰 파일을 세그먼트라고 하는 작은 조각으로 나누고 각 세그먼트에 고유 시퀀스(SEQ)번호를 할당합니다. 아래 그림을 보면 Host B는 “DATA”라는 내용을 전달하기 위해 “DA”“TA” 2 개의 조각으로 나누는 것을 볼 수 있습니다.

Reassemble segments 
Port 80 
HTTP 
TCP 
ACK 4 
Acknowledge each segment ACK 5 
Host A 
SEQ 
Source port: 36890 
Destination port: 80 
Break up file into segments 
HTTP 
TCP 
Host B 
C PcansenWinformationandÄCKånasing e 
message
  1. 그림에서 TCP는 첫번째 조각 “DA”에 대해서 시퀀스(SEQ) = 3을 할당하고 Host A로 보내게 됩니다.
  2. Host A는 수신 확인을 위해 ACK(Acknowledgement) 번호 = 4 패킷을 보냅니다.
    즉, “SEQ=3을 받았으니 다음 SEQ=4를 보내주세요.”라는 응답을 하게 됩니다.
  3. 그런 다음에, Host B가 다음 조각 “TA”를 SEQ = 4와 함께 Host A에게 보내게 됩니다.
  4. 그러면 Host A는 ACK=5를 전송하여 수신 확인 메시지를 보내게 됩니다.
  5. Host A는 모든 조각을 수신하게 되면, 순서에 맞게 조립하여 애플리케이션에 전달합니다.

포트 번호

앞서 설명한대로 TCP는 말 그대로 전송을 위한 매개체 역할을 합니다. 애플리케이션에서 데이터 전달을 명령하면 그 중간에서 일하는 직원 역할을 수행합니다. HTTP, FTP 등 기타 많은 애플리케이션에서 요청을 수신하게 됩니다.
마치 애플리케이션들이

“이봐 TCP, 저기 호스트와 연결을 설정하고 내 데이터가 안정적으로 도달하는지 확인해.”

라고 얘기하는 것으로 비유할 수 있습니다.

TCP는 목적지 대상의 포트 번호를 사용하여 서비스를 제공하는 각 애플리케이션을 추적합니다. 이를 위해 각 애플리케이션에는 표준 포트 번호가 할당됩니다.

Port 80 
HTTP 
I DATA 
Port 20 
FTP 
I DATA 
DATA 
Source port: 36890 
Destination port: 80 
HTTP 
I DATA I 
I 
Source port: 9245 
Destination port: 20 
FTP 
DATA 
I 
TCP 
TCP 
DATA 
Host A 
DATA 
Host B 
DAT 
Well-known applications use 1-1024 ports 
Ephemeral ports are 1025-65535

일반적으로, FTP는 데이터 전송을 위해 20번 포트 번호를 사용하고, HTTP는 80번 포트 번호를 사용합니다. Host B가 HTTP의 데이터를 처리한다면 목적지 포트 = 80이라고 설정하게 됩니다.

그럼 Host A는 목적지 포트 = 80으로 데이터를 수신하였기 때문에 DNS나 FTP가 아닌 HTTP 애플리케이션에 이 데이터를 전달해야 합니다. TCP는 최대 65,536개의 포트를 사용할 수 있지만, 처음 1,024개의 포트 번호는 잘 알려진 애플리케이션을 위해 사용합니다. 1025 ~ 65535번의 포트는 사용 후에 삭제하는 포트 번호(Ephemeral Port)로 알려져 있습니다.

TCP 헤더 구조

아래 그림은 TCP 헤더의 구조를 보여주고 있습니다. 이 헤더에서 가장 중요한 필드들을 특별히 강조하면서 설명해보도록 하겠습니다.

Distinguish between sessions 
Source Port 
Indicates app: HTTP, FTP, etc. 
Destination Port 
Sequence 
Acknowledgement 
Reliability 
10.1.1.1 
Host A 
Header 
Reserved 
Length 
Checksum 
Window Size 
Urgent Pointer 
Options 
Establish, maintain, teardown end-to-end connection 
Flow Control 
10.2.2.2 
Host B
목적지 포트(Destination Port)

헤더의 첫 필드는 출발지와 목적지 포트 번호입니다. 위에서 얘기했던 것처럼 Host는 목적지 포트를 사용하여 다양한 애플리케이션을 구반하게 됩니다.  하지만, 만약 두 개 이상의 HTTP 연결을 사용하게 되면 어떻게 구분할까요?

예를 들어, 내가 웹 브라우저를 열어서 egstroy.net 이라는 이 블로그를 즐겨찾기로 등록해서 들어오는 것과 검색엔진으로 직접 검색한 후 클릭해서 들어오는 것 모두 목적지 주소도 같고 포트 번호도 80을 사용합니다.

이런 경우, TCP는 출발지 포트(Source Port)를 임의 번호로 설정합니다.
즉, 검색 엔진을 통한 세션은 출발지 포트 = 58936 / 목적지 포트 = 80, 즐겨찾기를 통한 세션은 출발지 포트 =57576, 목적지 포트 = 80으로 설정되어 동일한 애플리케이션을 사용하더라도 TCP는 여러 개의 동시 세션을 구분할 수 있게 됩니다.

시퀀스 및 승인 번호 (Sequence & Acknowledgement)

시퀀스와 승인 (SEQ & ACK)에 대한 내용은 앞에서 다룬 내용 그대로입니다. ACK 및 SYN 플래그와 함께 사용되어 신뢰성과 흐름 제어(Flow Control)를 보장합니다.

Host B가 SEQ = 5를 보내게 되면, Host A는 ACK = 6으로 응답합니다.

하지만, 만약 Host A가 ACK = 5로 응답하게 된다면? Host B는 “음.. Host A가 SEQ = 5를 받지 못한 것 같으니 다시 보내겠습니다.”라고 하면서 다시 데이터를 전송하게 됩니다. 이러한 방식으로 TCP는 전송시 손실된 패킷을 다시 전송하여 안정성을 보장합니다.

플래그 (Flags)

우리는 TCP 패킷(시퀀스)번호를 동기화하고 패킷 수신을 확인하기 위해서 SYN과 ACK 플래그를 사용하는 것을 이미 알고 있습니다. 그 외에도, 수신자에게 “Host A! 이 파일이 마지막 조각입니다.”라고 알려주는 FIN(Final) 플래그도 있습니다.

URG(Urgent), PSH(Push) 플래그는 특정 데이터가 긴급하게 수신 애플리케이션으로 신속하게 전송되어야 할 때 사용되는 플래그입니다. URG 플래그는 긴급 데이터가 있는 위치를 나타내는 Urgent Pointer 필드와 함께 사용됩니다. 그리고 연결을 재설정하는데 사용되는 RST(Reset) 플래그도 있습니다.

체크섬(Check Sum) & 윈도우 사이즈 (Window Size)

신뢰성을 위한 체크섬과 플로우 제어에 사용되는 윈도우 사이즈 필드가 있습니다. 만약 Host B가 한 번에 너무 많은 데이터를 보내게 되어서 Host A가 부하가 걸려서 처리하지 못할 수도 있습니다. 이럴 때 Host A는 B에게 “한 번에 많은 데이터를 보내지 마세요. 속도를 줄여주세요.”라고 하면서 윈도우 사이즈를 줄일 수 있게 됩니다.

이 밖에 나머지 필드는 향후 포스팅에서 기회가 되면 다뤄보도록 하겠습니다.

다음 포스팅에서는 Layer 4의 또 다른 프로토콜, UDP를 다뤄보도록 하겠습니다.