Published on

IPv4 Fragmentation : 네트워크-5

Fragment and Reassembly

IP는 network layer의 핵심적 기능을 담당한다.
Network layer의 책임 중 하나는 서로 다른 물리적 환경의 네트워크들을 연결하고 상위 계층에 각 노드들의 인터페이스를 추상화하여 제공하는 것이다.

서로 다른 물리적 환경은 곧 통신 환경도 모두 제각각이란 것을 말하는데,

이에 영향을 받는 요인으로는 transmission speed와 maximum transmission unit(MTU)가 있다.

transmission speed는 말 그대로 전송 속도[bytes/sec]를 말하고 MTU는 한 번의 송신에서 보낼 수 있는 최대 프로토콜 데이터 단위(PDU)를 말한다.

만약 어떤 네트워크에서 다른 네트워크에 datagram을 보낼 때, 다른 네트워크가 datagram보다 작은 MTU를 지니고 있는 경우, 이러한 패킷은 MTU를 감당할 수 있게 쪼개져야만 할 것이다.

IPv4의 경우 이러한 역할을 라우터를 통해 직접 수행하여 서로 다른 물리적 환경에 상관없는 통신을 보장하고, 호스트에게 이 문제를 노출하지 않으려 노력한다.

과거엔 좋지 않은 개인 컴퓨터의 성능에 맞물려 Dummy Device, Smart Network를 지향하던 전략으로 여러 복잡한 문제를 호스트에게 노출시키기 보단 네트워크에서 최대한 해결하려 노력했던 것이다.

그러나 각종 컴퓨터의 성능이 비약적으로 발전하고 네트워크 트래픽이 어마어마하게 늘어난 오늘날에는 상황이 Smart Device, Dummy Network로 바뀌고 있다.

나중에 얘기하겠지만, IPv6의 경우 fragmentation을 수행하지 않는다.
대신 MTU 탐색의 책임을 호스트에게 맡겨버린다.

이제 Fragmentation에 대해서 좀 더 자세히 알아보자.

Fragmentation

라우터는 패킷을 받고 패킷이 갈 포트와 MTU를 검증한다.
만약 패킷 크기가 MTU보다 크고 DF가 0으로 설정되었을 때 라우터는 fragmentation을 수행한다.

이 때 fragment(쪼개진 패킷)의 크기는 MTU - IP header size(20 ~ 60 bytes)가 된다.

새로운 패킷들에서 달라지는 정보는 다음과 같다.

  1. 전체 길이(total length field)
  2. MF=1 (마지막 fragment는 제외된다.)
  3. fragment offset field가 설정된다.
  4. header checksum

만약 어떤 IPv4 패킷이 20 bytes 헤더를 포함한 4520 bytes크기를 갖는다고 하자.

이제 이 패킷이 만약 MTU = 2500 bytes를 갖는 어떤 링크에 도달한다면,

다음과 같이 분할될 것이다.

Fragmentsize (bytes)Header size (bytes)Data size (byets)More FragmentsFragment Offset (8 bytes block)
12,500202,48010
22,040202,0200310

만약 두 패킷이 이젠 MTU = 1500 bytes인 링크를 만난다면

Fragmentsize (bytes)Header size (bytes)Data size (byets)More FragmentsFragment Offset (8 bytes block)
11,500201,48010
21,020201,0001185
31,500201,4801310
4560205400495

Reassembly

receiver는 도달한 패킷이 fragment라는 것을 어떻게 알까?

첫 번째론 MF(More Fragement) bit를 보고 판단한다. MF bit는 마지막 fragment를 제외하고 항상 1로 set되기 때문에 MF=1이라면 패킷이 fragment라는 것을 보장받을 수 있다.

두 번째는 fregment offset을 보는 것이다.
첫 번째 패킷을 제외한 모든 fragment는 nonzero fragment offset을 가진다.

따라서 위의 두 조건 중 하나라도 만족하면 패킷이 fragment라고 판단할 수 있다.

receiver가 패킷이 fragment임을 알게 되면 fragment들을 모아 원본 패킷을 만들어낸다.

이 떄 사용하는 것이 바로 Identification field이다.

Identification 필드는 fragment들을 이어주는 값으로 하나의 패킷에서 쪼개진 fragment들은 모두 같은 identification 값을 가진다.

만약 어떤 fragment 패킷이 도작했다면 패킷의 fragment offset을 기반으로 어떤 버퍼에 저장해둔 뒤, 이후 도착하는 같은 identification들을 차곡차곡 버퍼에 저장하여 원본 데이터를 조립한다.