지식

[Network] 네트워크 기초 이론 14강 — 패킷의 생성 원리와 캡슐화: 헤더는 송장, 페이로드는 내용물

네트워크 기초 이론 시리즈 정리 — 14강. 참고: 널널한 개발자 TV, 패킷의 생성 원리와 캡슐화 (재생목록)

7강에서 계층별 데이터 단위를 정리하며 인캡슐레이션의 구체적인 형태는 14강에서 다룬다고 미뤄 두었다. 이번이 그 편이다 — send() 한 번에 무슨 일이 벌어져 스트림이 패킷이 되는지, 패킷 안은 실제로 어떻게 생겼는지를 본다. 이 그림은 네트워크와 개발 양쪽에 걸쳐 있어서, 소켓 프로그래밍을 하는 개발자에게나 패킷을 들여다보는 네트워크 쪽에나 똑같이 기본기가 된다.

데이터가 내려가는 길

먼저 무대를 다시 그린다. 유저 모드의 애플리케이션 프로세스는 소켓으로 TCP/IP에 접근한다(1강 — 소켓은 파일의 일종이고, 모든 프로그램은 파일을 열어 읽고 쓴다).

유저 모드 :  [ 애플리케이션 프로세스 ]
                      │  소켓 (파일 형태의 인터페이스)
커널      :       TCP / IP

                디바이스 드라이버

하드웨어  :         NIC ──── 랜케이블 ──── 인터넷

소켓 수준에서 데이터의 단위는 스트림이다 — 시작은 있지만 언제 끝날지는 정해져 있지 않은, 일렬로 늘어선 데이터. 끝은 그 프로그램을 만든 개발자가 결정한다.

send()를 누르는 순간

애플리케이션이 스트림 데이터를 담아 send()류 함수를 호출하면, 그 아래에서 두 가지 변형이 연쇄로 일어난다.

  1. 세그멘테이션 — 내려가던 스트림이 TCP를 만나는 지점에서 일정 단위로 잘린다. 잘린 조각이 세그먼트다.
  2. 인캡슐레이션 — 세그먼트가 한 번 포장되면 패킷, 패킷이 한 번 더 포장되면 프레임이 된다(이더넷 네트워크라면 이더넷 프레임).

여기까지는 7강의 복습이다. 이번 강의 본론은 그 "포장"의 실제 생김새다.

패킷의 해부 — 헤더와 페이로드

패킷은 크게 둘로 나뉜다. 앞의 헤더(header) 와, 실어 나르는 몸통인 페이로드(payload). 그리고 헤더를 확대하면 다시 둘이다 — 맨 앞에 IP 헤더, 그 뒤에 TCP 헤더가 붙는다.

│← IP 헤더 →│← TCP 헤더 →│←──────── 페이로드 ────────→│
│   20바이트  │   20바이트   │   세그먼트 (스트림의 조각)     │
│←────────────── 패킷 : 최대 1500바이트 = MTU ──────────────→│

읽는 방향에 규칙이 있다. 왼쪽에서 오른쪽으로 갈수록 계층이 올라간다 — L3(IP)가 먼저, L4(TCP)가 다음, 그 뒤가 상위의 데이터다.

숫자를 채워 보자. 패킷의 최대 크기는 MTU, 특별한 이유가 없으면 1500바이트다. IP 헤더와 TCP 헤더는 옵션이 없으면 각각 20바이트. 그러면 페이로드의 몫은:

1500 − 20 − 20 = 1460바이트 = MSS

7강에서 공식으로만 봤던 MSS가 여기서 실체를 갖는다. TCP는 스트림을 1460바이트씩 계속 끊어내고, 그 조각 하나하나를 페이로드 자리에 넣은 뒤 앞에 헤더를 붙인다. 이것이 패킷의 생성 원리 전부다.

택배로 다시 보기

이 구조는 택배에 정확히 대응된다.

네트워크 택배 비고
패킷 택배 상자 운반되는 단위 그 자체
헤더 송장 보낸 이·받는 이 — 운반에 필요한 정보
페이로드(세그먼트) 내용물 상자 안에 든 실제 물건
인캡슐레이션 내용물을 상자에 넣기 부수는 게 아니라 감싸서 넣는 것
프레임 택배를 실은 트럭 상자가 트럭에 실리는 한 번 더의 캡슐화

송장은 상자 밖에 붙는다 — 어쩔 수 없이 노출된다. 그게 있어야 기사가 상자를 집어 옮길 수 있기 때문이다. 헤더도 같다. 경로상의 장비들은 헤더를 읽어야 패킷을 다음으로 넘길 수 있으므로, 헤더는 구조적으로 공개된 정보다.

그리고 트럭까지 오면 계층 대응이 완성된다 — 세그먼트는 L4, 패킷은 L3, 프레임은 L2 수준의 데이터 단위다.

DPI — 페이로드까지 들여다본다면

헤더가 아니라 페이로드 안쪽까지 조사하는 것DPI(Deep Packet Inspection) 라고 한다. 택배로 치면 송장 확인이 아니라 상자를 열어 내용물을 검사하는 일이다.

보안 장비가 유해 트래픽을 걸러낼 때 쓰는 핵심 기법이지만, 같은 이유로 감청의 성격을 갖는다 — 송장은 운반을 위해 원래 공개된 정보지만 내용물은 그렇지 않기 때문이다. 여기서는 용어와 그 무게만 잡아 두면 된다: 페이로드를 뒤지는 것 = DPI.

개발자에게 갖는 의미 — send 한 번 ≠ 패킷 한 개

소켓 프로그래밍을 하는 입장에서 이 그림이 주는 실감 나는 결론이 하나 있다. send()로 2000바이트를 보냈다고 하자. 페이로드 상한이 1460바이트이므로 이 데이터는 패킷 하나에 못 들어간다 — 최소 두 개의 패킷으로 쪼개져 날아간다.

즉 애플리케이션이 인식하는 "한 번의 전송"과 네트워크를 실제로 흐르는 패킷 사이에는 1:1 대응이 없다. TCP가 스트림 지향이라는 말(7강)의 실체가 이것이다. 상대편도 내가 보낸 덩어리 단위가 아니라 이어진 스트림으로 받는다 — 메시지의 경계는 프로토콜을 설계하는 개발자가 스스로 정의해야 한다.

정리

  • 패킷의 생성: 프로세스가 소켓에 스트림을 쓰면 → TCP가 1460바이트(MSS) 단위로 세그멘테이션 → 각 조각을 페이로드로 삼아 헤더를 붙여 인캡슐레이션한 것이 패킷이다.
  • 패킷 = 헤더 + 페이로드. 헤더는 다시 IP 헤더(20B) + TCP 헤더(20B) 이고, 왼쪽에서 오른쪽으로 계층이 올라간다.
  • 택배 대응 — 상자=패킷, 송장=헤더, 내용물=세그먼트, 트럭=프레임. 송장(헤더)은 운반을 위해 구조적으로 노출된다.
  • 계층 대응 — 세그먼트 L4, 패킷 L3, 프레임 L2.
  • 페이로드까지 조사하는 것이 DPI다. 보안의 도구이자 감청의 문제가 겹치는 지점이다.
  • send() 한 번이 패킷 하나를 보장하지 않는다 — 2000바이트면 최소 두 패킷이다. 메시지 경계는 애플리케이션의 몫이다.
조회 1댓글 0

댓글

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.