요약
정리
프로세스가 네트워크로 데이터를 보내려면 커널의 TCP/IP 프로토콜 스택에 접근해야 한다. 이때 쓰는 것이 Socket이다. Socket은 프로토콜 스택에 대한 추상화된 endpoint로, socket() syscall로 fd를 얻는다. Unix/Linux에서는 파일의 일종이지만 장치 파일(device file)과는 별도의 파일 타입이다.
Socket을 통해 send()로 데이터를 쓰면, TCP는 이것을 경계 없는 연속된 바이트 흐름, 즉 byte stream으로 취급한다. 시작(3-way handshake)과 끝(FIN)은 있지만 메시지 경계는 없다. 100byte를 2번 보내도 수신 측이 200byte를 1번에 읽을 수 있다. stream은 PDU가 아니라 application에 제공되는 추상화다.
그런데 이 stream을 그대로 네트워크에 흘려보낼 수는 없다. 물리 링크에는 한 번에 보낼 수 있는 크기 제한이 있기 때문이다. Ethernet의 MTU(Maximum Transmission Unit)는 1500byte이고, 여기서 IP header(20byte)와 TCP header(20byte)를 빼면 TCP payload 최대 크기인 MSS(Maximum Segment Size)는 1460byte가 된다. TCP는 이 MSS를 기준으로 stream을 잘라 Segment를 만든다. 2000byte를 send()하면 1460 + 540, 2개의 segment가 된다.
Segment가 만들어지면 아래 계층으로 내려가며 **캡슐화(Encapsulation)**가 일어난다. Transport(L4)에서 TCP header를 붙여 segment를 만들고, Network(L3)에서 IP header를 씌워 Packet이 되고, Data Link(L2)에서 Ethernet header와 trailer를 붙여 Frame이 된다. 비유하면 편지(payload)를 봉투에 넣고(packet), 봉투를 택배 상자에 넣는(frame) 것이다. 수신 측에서는 역순으로 header를 벗겨낸다(decapsulation).
이렇게 캡슐화된 packet의 내부, 즉 payload까지 열어보는 검사 방식이 DPI(Deep Packet Inspection)다. 일반 검사는 header(IP, port)만 보지만, DPI는 application 데이터까지 분석하여 방화벽, IDS, 트래픽 분류에 활용한다. 다만 TLS로 암호화된 트래픽에는 복호화 없이 적용할 수 없다.
참고
https://m.youtube.com/watch?v=Bz-K-DPfioE&pp=ygUW7Yyo7YK3IOunjOuTpOyWtOyngOuKlA%3D%3D
참고
Socket - 프로세스가 네트워크에 접근하는 인터페이스 Encapsulation와 PDU(Protocol Data Unit)를 이용해서 OSI의 추상화를 구현한다. TCP Byte Stream -- Transport Layer의 추상화다.