TCP Header를 알면 TCP를 이해할 수 있다

김나연·2021년 11월 20일
1

Header를 알면 프로토콜을 이해할 수 있다! 는 게 내 생각...이므로 오늘은 TCP Header에 대해 분석해보기로 한다.

Sourece Port, Destination Port

송신자와 수신자의 포트 번호

16bit, 16bit

0~65536 중 하나의 포트를 사용한다.
만약 클라이언트인 내가 어떤 웹 서버와 HTTPS로 연결하게 된다면, Source Port에는 내 랜덤한 포트가 들어갈 것이고, Destination Port에는 HTTPS 포트인 443이 들어가게 될 것이다.

번외로 이것과 관련해서 서칭을 하다가 흥미로운 스택오버플로우 질문을 발견했다: https://stackoverflow.com/questions/21253474/source-port-vs-destination-port?newreg=5c078a96a68147428f81aeffb215ebdf

Q. 트래픽을 수신할 땐 제 브라우저가 80번 포트를 사용하지 않는데요. 하지만 제가 80번 포트를 닫는다면 인터넷이 동작하지 않습니다. 왜 그런 건가요?
A. 통신은 당신의 컴퓨터(송신포트='랜덤')로 부터 웹 서버(수신포트=80)로 진행됩니다. 하지만 당신이 80번 포트를 닫는다면 어떤 웹 서버에도 접속하지 못 할 것입니다. 그렇게 한다면 당신의 방화벽이 당신의 컴퓨터로부터 80번포트로 보내지는 어떤 패킷이라도 전부 탈락시킨다는 것을 의미하기 때문입니다.
수신할 때는 다른 포트를 쓰지만, 송신의 80포트를 닫는다면 패킷을 못 받는다고 한다.

Sequence Number

데이터의 고유한 번호

32bit

SYN Flag를 설정했을 때 사용되는 번호이다.

TCP는 데이터를 보낼 때마다 데이터에 고유한 번호를 부여한다. 이 번호를 사용해서 수신자가 중복된 데이터를 폐기하거나 아니면 순서가 뒤바뀌어 수신됐을 때 데이터를 순서대로 재구성할 수 있다.

ISN (Initial Sequence Number)

여기서 알아야 할 ISN이란? TCP는 새로운 연결을 할 때마다 새로운 Sequence Number를 사용하는데 여기서 최초로 랜덤하게 골라서 보내지는 게 ISN이 되는 것이다. ISN은 0부터 4,294,967,295까지의 아무 값이나 될 수 있다.

엄청 큰 수이긴 한데... 만약 ISN값이 중복이 된다면 어떻게 될까?
일반적으로 4ms마다 Sequence Number의 값이 변화되기 때문에 ISN값은 4.55시간에 한 번씩 동일해진다. 하지만 네트워크에서 패킷이 살아있는 시간(Maximum Segment Lifetime)은 항상 4.55시간 보다 작다. 그래서 ISN값은 항상 유니크하게 생성됨을 보장한다.

MSL (Maximum Segment Lifetime)

네트워크에서 패킷이 살아있는 시간. IP의 TTL과 비슷하다. 이 시간이 지나면 라우터에서 패킷을 폐기한다. RFC1122에서는 보통 이 시간이 2분 정도일 것이라고 말한다.

"The TCP specification [TCP:1] arbitrarily assumes a value of 2 minutes for MSL. This sets an upper limit on a reasonable reassembly timeout value." - https://www.ietf.org/rfc/rfc1122.txt

Acknowlegment Number

데이터 수신 응답 번호

32bit

여기서 3-way Handshaking을 떠올리자!

송신자가 처음으로 연결을 확립하는 요청을 때 SYN을 랜덤하게 골라서 보내고 나면, 수신자는 송신자가 보낸 SYN에다가 +1을 한 값을 ACK Number로 보낸다. 이것은 송신자가 직전에 보낸 패킷을 잘 받았다는 의미가 된다.

+1을 하는 이유는, 그래야 무슨 패킷을 잘 받았다는 건지 알 수 있기 때문이다. TCP의 섬세한 패킷 순서 보장이 보이는 부분인 것 같다.

Data Offset

TCP 헤더의 크기 값, 즉 데이터의 시작 위치

4bit

헤더가 끝나면 데이터가 시작되니까 당연히 위 두 개는 같은 말이 된다.

헤더의 크기는 최소 20byte(5워드), 최대 60byte(15워드)가 된다. 왜 최소가 20byte냐면 헤더에서 Options를 제외한 다른 필드들의 합이 모두 20byte이기 때문이다.
20byte = 160bit = 16 + 16 + 32 + 32 + 4 + 3 + 9 + 16 + 16 + 16bit!

Reserved

차후의 사용을 위해 예약된 필드

3bit

미래를 위해서 만들어놓은 예약 필드로, 항상 0으로 설정되어있어야 한다.

하지만, "It is only a matter of time before a suggestion for using the flag is made."
라고 한다...! 바로 밑에서 추가된 ECN 플래그에 의해 사용되기도 한다. 원래 6bit였는데 3bit로 줄었다.

Flags

세그먼트의 용도와 내용을 결정하는 플래그

9bit

기존 스탠다드 였던 헤더는 URG, ACK, PSH, RST, SYN, FIN이었다.
여기서 URG가 set되어 있으면 Urgent Pointer에 값이 있다는 걸 의미하고 다른 데이터보다 먼저 보아야 할 데이터가 있다는 걸 의미한다.

PSH는 수신자에게 버퍼링된 데이터를 푸시할지 여부를 가르킨다.

RST은 커넥션을 리셋하겠다는 의미로, 이것이 1로 set되어 있는 세그먼트를 받으면 즉시 연결을 끝는다.

ACK, SYN은 앞서 설명한 Acknowledge Number와 Sequence Number가 있는지를 가르킨다.

ACK Flag는 클라이언트가 보낸 최초의 SYN 패킷 이후에 전송되는 모든 패킷에 설정되어 있어야 하지만, SYN Flag는 양쪽이 최초에 보낸 패킷에만 설정되어 있어야 한다.

FIN은 더이상 보낼 데이터가 없다는 것을 의미한다. 연결 종료 과정인 4-way Handshaking 때 이 비트를 사용한다.

기존에는 6개의 플래그만 사용했지만 RFC 3168, 3540에 의해 추가된 플래그가 더 있다. 모두 명시적 혼잡 제어 기능(Explicit Congestion Notification, ECN)을 위해서 사용되는 것으로, Reserved 필드를 이용한다. 바로 NS, CWR, ECE다.

NS는 ECN에서 사용하는 CWR, ECE 필드가 실수나 악의적으로 은폐되는 경우를 방어하기 위해 RFC 3540에 추가된 필드다.

CWR은 Congestion Window Reduced의 약자로, 혼잡 제어 메커니즘에 의해 응답했음을 알리는 의미라고 한다. ECE 플래그를 받아서 윈도우의 크기를 줄였다는 의미다. RFC 3168에 의해 추가되었다.

ECE는 ECN Echo 플래그로, 해당 필드가 1이면서 SYN이 1일 때는 ECN을 사용한다고 알리는 것이다. 만약 SYN이 0이라면 네트워크가 혼잡하므로 윈도우의 크기를 줄여달라는 의미다.

Window Size

수신하고자 하는 윈도우의 크기

16bit

이것은 수신 프로세스가 수신할 수 있는 바이트 수를 의미한다. TCP의 흐름 제어 메커니즘인 Sliding Window에서 사용되는 것이다. 수신자가 너무 많은 데이터를 받아서 감당하기 어려울 경우엔 이 사이즈를 줄인다. 송신자는 해당 사이즈 만큼만 데이터를 전송해야만 한다.

Checksum

오류 검출을 위해 사용되는 필드

16bit

헤더 및 데이터를 16bit 단위로 분할하여 비트 합을 구한 뒤 여기에 1의 보수를 취한 값이다. 송신자는 이 알고리즘에 의해 계산된 체크섬을 이 필드에 삽입하고, 송신자는 같은 알고리즘으로 계산해서 동일한지 확인한다. 만약 비트 합 계산 중 Carry가 발생되면 Wrap Around를 적용한다.

Urgent Pointer

긴급 데이터가 시작되는 위치

16bit

Flags에서 URG Flag가 설정된 경우만 사용한다. 일반 데이터 내에서 주요한, 긴급한 데이터가 시작되는 위치를 가르키는 필드다.

Options

TCP 기능을 확장할 때 사용

0byte ~ 40byte

앞서 TCP 헤더의 크기가 20byte에서 최대 60byte까지 될 수도 있다고 서술했는데 바로 이 Options 필드 때문이다. 이 필드는 가변적인 크기를 가지고 있기 때문에, 어디까지가 Header고 어디부터가 Data인지 알기 위해 Data Offset이 필요한 것이다.

여담.
CS 과목 중에 가장 재밌는 게 데이터베이스랑 네트워크인 것 같다.

References

Thanks to...
https://www.ietf.org/rfc/rfc1122.txt
https://datatracker.ietf.org/doc/html/rfc4413#section-4.2.3
https://joycecoder.tistory.com/13
https://nogan.tistory.com/24
https://m.blog.naver.com/tkdldjs35/221838726823
http://www.deadfire.net/tcpip/tcpip20.html
https://kosaf04pyh.tistory.com/218

0개의 댓글