티스토리 뷰

TCP/IP를 공부하던 중 TCP는 데이터 송수신의 순서를 보장한다는 글을 읽었다. 학교에서 네트워크 수업을 들을 때 분명히 패킷이 분할되고 재조립하는 과정을 거친다고 했었다. 송신측에서 전달한 데이터는 패킷으로 분할되고, 패킷은 라우터를 거치며 수신측으로 보내지기 때문에 수신측에 패킷이 도착하는 순서가 보장되지 않는다는 생각이 문득 들었다.

 

패킷이 수신측에 순서대로 도착하지 않는데 TCP는 왜 순서를 보장하지? 라는 의문이 생겨서 관련 내용을 쭉 찾아봤는데, 추상적으로 설명해놓은 글이 많아 정리하려고 한다.

 

TCP/IP

 

네트워크 통신을 위한 과정을 분류하는 모델로 OSI 7 계층이라는 표준이 존재한다. 우리가 HTTP 통신을 하기 위해 주로 사용하는 TCP/IP 프로토콜을 OSI 7 계층에 맞추어 추상화한 것이 위 그림의 TCP/IP 모델이다. HTTP 요청이 발생하면 Application -> Transport -> Internet -> Network 계층을 지나가며, 각 계층에서 담당하는 헤더를 추가해 수신측으로 요청을 전송하는 흐름이다.

 

TCP/IP를 보통 함께 부르곤 해서 TCP와 IP를 하나의 세트처럼 생각했는데, 두 개는 별도의 프로토콜이고 분리하여 이해해야 한다. TCP는 위 그림에서 Transport 영역이고, IP는 Internet 영역이다. OSI 계층으로 생각하면 L4가 TCP, L3가 IP이다.

 

간단하게 Transport와 Internet 계층에 대해 설명하면

 

Transport Layer(L4)

송신자와 수신자의 논리적 연결(connection)을 담당하는 부분으로, 신뢰성 있는 연결을 유지하도록 한다. 즉 End to End 간의 연결을 생성하고 데이터를 얼마나 보내고 받았는지, 제대로 받았는지 등을 확인한다. 해당 계층에서는 TCP와 UDP가 대표적이다.

 

Internet Layer(L3)

IP(Internet Protocol)을 활용해 한 end에서 다른 end로 이동하는 경로와 목적지를 찾는다. 이를 Routing이라고 하며 대역이 다른 IP들이 목적지를 향해 제대로 찾아갈 수 있도록 한다.

 

즉, TCP는 통신하고자 하는 양쪽 단말(EndPoint)가 준비 되었는지, 데이터가 제대로 전송되었는지, 사라지지는 않았는지, 데이터를 얼마나 받았는지와 같이 점검하는 역할을 하고 IP는 그저 목적지를 제대로 찾아가는 역할을 한다.

그래서 TCP 헤더에는 SYN, ACK, FIN, RST, Source Port, Dest Port, Sequence Number, Window Size, Checksum과 같은 신뢰성 보장과 흐름 제어, 혼잡 제어에 관여할 수 있는 요소들이 포함되어 있다.

 

IP 헤더에는 Packet Length, Header Checksum, Source IP, Destinaition IP와 같이 상대에게 전달하는 과정에 관여할 수 있는 요소들이 포함되어 있고, 그 중에 패킷 분할과 재조립에 관련되어 있는 Flag와 Fragment Offset이 있다.


TCP Fragments

MTU는(Maximum Transmission Unit)의 약자로 한 패킷으로 운반할 수 있는 디지털 데이터의 최대 길이를 말하며, 이더넷에서는 보통 1,500바이트가 된다. MTU에는 패킷의 맨 앞부분에 헤더(TCP, IP)가 포함되어 있으므로, 헤더부를 제외한 부분이 하나의 패킷으로 운반할 수 있는 데이터의 최대 길이가 되며 이를 MSS(Maximum Segment Size)라고 한다.

 

만약 블로그 일기나 게시판 글과 같은 용량이 큰(MSS 이상) 데이터를 전송하는 경우가 발생하면 해당 데이터는 한 번에 전송할 수 없다. 그런 경우 패킷을 MSS 이하의 조각으로 분할해야 한다. 이렇게 분할하는 것을 단편화(Fragmentation), 분할된 조각을(Fragment)라고 한다. MSS 값은 고정된 값이 아닌, 수신측과 송신측이 서로 합의하여 결정된다.

 

 

그러면 전송 계층의 TCP 프로토콜이 응용 계층의 데이터 단위인 메시지를 받아 작은 조각으로 분할한다. 해당 데이터 단위를 세그먼트(segment)라고 한다. 즉, TCP 프로토콜에 따라 분할된 데이터에 TCP 헤더가 붙어 캡슐화된 전송 계층의 패킷이 세그먼트이다.

 

분할된 데이터에 순서 번호(Sequence Number)를 부어해 전송 과정에서 전송 순서가 뒤바뀌더라도, 수신지에서 원래의 데이터로 재조립할 수 있다.

 

전송 계층 to 전송 계층으로 보면 TCP는 순서가 보장되는 신뢰할 수 있는 프로토콜이다. 왜냐하면 송신측의 전송 계층은 보내는 세그먼트마다 Sequence Number를 붙여서 전송하고, 수신측의 전송 계층은 원하는 Seqeunce Number에 해당하는 세그먼트가 도착하는지 도착하지 않는지만 판단하면 된다. 만약 해당 Sequence Number에 해당하는 세그먼트가 도착하지 않으면, 수신측에 다시 보내달라고 요청하면 된다.


IP Fragments

IP 패킷 분할은 TCP에서와 마찬가지로 IP 패킷의 크기가 MTU보다 클 때 IP Fragments가 발생하게 된다. 모든 패킷이 분할되는 것은 아니고, 애플리케이션 계층에서 분할 불가로 지정한 경우에는 분할되지 않는다. 그렇다면 IP 패킷 분할은 어디서 발생할까?

 

인터넷 계층은 전송 계층으로 부터 받은 세그먼트에 IP 헤더를 붙인다. IP 헤더에는 Packet Length, Header Checksum, Source IP, Destinaition IP, Identification, Fragments offset 등이 기록된다. 인터넷 계층에도 전송 계층과 마찬가지로 해당 계층의 MTU를 넘어선 패킷을 전송할 수 없다. MTU는 계층마다 다르다. 그렇기 때문에 거치는 라우터 마다 전송에 적합한 데이터 링크 계층 프레임으로 변환이 필요하다. IPv4에서는 발신지 뿐만 아니라 중간 라우터에서도 IP 단편화가 가능하다.

 

또한 라우터의 포트는 이더넷 뿐만 아니라 이더넷 이외의 LAN이나 통신 회선의 경우가 존재한다. 이 회선이나 LAN의 종류에 따라 패킷의 최대 길이가 달라지므로 출력 포트측의 패킷의 최대 길이가 입력측보다 작은 경우도 있다. 이 경우에도 IP 패킷 분할이 발생한다.

 

TCP의 분할과 IP 분할이 다른 점은, TCP의 데이터 분할은 패킷에 데이터를 저장하기 전에 이루어진다. 즉, 분할한 데이터 조각을 한 개의 패킷에 저장한다. 이 패킷은 한 개이므로 IP의 입장에서는 분할되지 않는 데이터이다. 반면에 IP 패킷 분할은 패킷이 만들어진 후에 패킷을 분할한다. 그러므로 데이터들이 조각조각 나있는 것이다.

 

만약 애플리케이션에서 분할 불가로 지정한 경우에는 그대로 패킷을 버린다.

 

패킷이 분할될 때 마다 IP 헤더의 Identification, Fragments offset 값이 기록된다. 분할된 패킷들이 목적지에 도착하면 패킷이 재조립과정을 거치게 되는데 이 과정을 reassembling 이라고 한다. Reassembling을 할 때는 아래 정보를 참고해 재조립과정을 거치게 된다.

 

  • Identification : 같은 패킷에서 분할되었다는 것을 알기위한 식별자
  • Don't Fragment : 분할된 패킷에는 0, 분할되지 않은 패킷에는 1 부여
  • More Fragment : 분할된 패킷들 중에 마지막이 아닌 패킷들은 1이 부여되고, 마지막 패킷(조립할게 더 없을 때) 이거나 분할되지 않은 패킷일 경우에 0이 부여된다.
  • Fragemnt offset : 분할된 패킷이 분할되기 전에 패킷에서 상대위치를 나타낸다. 조립 과정에서 이 값을 보고 조립의 순서를 결정한다.

 

TCP는 순서가 보장되는 신뢰할 수 있는 프로토콜이지만, IP는 순서가 보장되지 않는 신뢰할 수 없는 프로토콜이다. IP 패킷은 전송되는 과정에서 분할될 수 있고, 분할된 패킷은 네트워크 상에 있는 라우터들을 거쳐 순서대로 도착함을 보장하지 않는다. 또한 패킷들은 라우터를 거치면서 버려질 수도 있다. 수신측에서 재조립과정을 거치지만, 전송 과정에서 패킷이 사라지거나 손상되는 경우 송신측에 다시 요청할 수 없다.

댓글