요약

  • IPv4의 ICMP 파라미터 문제는 거부와 설명을 분리했다. 잘못된 패킷은 폐기되었고, 8비트 포인터가 헤더에서 문제의 옥텟을 식별했다.
  • ICMPv6는 포인터를 32비트로 확장하고 잘못된 필드, 알 수 없는 Next Header, 알 수 없는 옵션을 구분했다. 반환된 인용이 도달하지 못하더라도 오프셋은 확장 헤더 체인을 따라갈 수 있었다.
  • 정밀한 포인터는 경계가 있는 근거이지 인증된 진실이 아니다. 어느 노드가 어디서 멈췄는지는 식별할 수 있지만, 발신자의 의도, 근본 원인, 현재 제품 동작, 인용된 바이트 이후의 안전한 접근을 증명하지는 못한다.

주소를 가진 실패

대부분의 패킷 손실은 침묵한다. 발신자가 전송하지만 유용한 응답이 돌아오지 않는다. 그 부재는 혼잡, 필터링, 잘못된 목적지, 끊긴 경로, 또는 단순히 또 하나의 손실된 패킷을 의미할 수 있다. 1981년 9월, RFC 792는 말을 할 수 있는 더 좁은 실패를 정의했다. IPv4 게이트웨이나 호스트가 계속 진행할 수 없을 만큼 헤더 파라미터가 심하게 잘못되었음을 발견하면 데이터그램을 폐기해야 했다. 동시에 ICMP 타입 12, 파라미터 문제를 반환할 수도 있었다.

그 메시지의 특징적인 필드는 문장이 아니었다. 8비트 포인터였다. 코드 0에서 이 값은 원래 IPv4 헤더에서 오류가 감지된 옥텟을 식별했다. 오프셋 1은 Type of Service 옥텟을 가리켰다. 옵션이 있었다면 오프셋 20은 첫 번째 옵션의 타입을 가리킬 수 있었다. 포인터는 옵션 중간에 착지할 수도 있었다. 그것은 수신자가 실제로 파싱하려 시도한 바이트들 안의 위치를 서술했다.

그 작은 숫자가 실패의 질을 바꾸었다. 일반적인 오류는 패킷이 작동하지 않았다고만 말한다. 포인터는 발신 측이 보고서를 자신의 직렬화기, 설정 또는 패킷 캡처와 비교하게 해 준다. 폐기 결정은 여전히 거부 노드의 몫이었다. 발신 측은 자신의 출력을 복구할 근거를 얻었다.

이 메시지는 원래 인터넷 헤더와 첫 64비트의 페이로드도 인용했다. 초기 TCP나 UDP 트래픽에서 그 처음 여덟 옥텟은 흔히 포트를 포함했고, 호스트는 오류를 프로세스와 연관 지을 수 있었다. 인용과 포인터는 서로 다른 목적을 담당했다: 인용은 맥락을 제공했고, 포인터는 감지된 결함의 위치를 정했다.

그러나 어느 쪽도 IP를 신뢰할 수 있게 만들지는 않았다. RFC 792는 ICMP를 피드백으로 명시적으로 서술하며, 폐기된 모든 데이터그램이 보고될 것이라는 보장이 아니라고 했다. ICMP 오류에 대해 오류가 재귀적으로 생성되지 않았고, 단편화된 트래픽에는 별도의 제약이 있었다. 침묵은 여전히 모호했다.

필드 오류에서 호스트 의무로

RFC 1122는 초기 형식을 호스트 동작으로 바꾸었다. 유용한 스택은 파라미터 문제 정보를 수신하고, 발신 프로세스를 식별할 수 있을 때 그것을 상위로 노출해야 했다. TCP의 경우, 파라미터 문제는 접속을 무조건 끊으라는 보편적 지시로 다루지 말고 보고되어야 했다. 이 오류는 전송 계층과 응용이 이용할 수 있는 근거에 속했고, 단순한 도착이 모든 응답을 결정하지는 않았다.

같은 호스트 요구사항 문서는 진단을 자원 제약 아래 두었다. 구현은 이상한 패킷의 충분한 부분을 조사용으로 기록하되, 오류 로깅이 감당할 수 없는 메모리·저장 공간·처리량을 소모해서는 안 되었다. 이 운영상의 균형은 후일 와이어 규칙을 예고했다: 유용한 맥락을 반환하되, 타 기계의 잘못된 입력을 설명하는 비용에 단단한 경계를 두는 것이다.

RFC 1812는 이 규율을 IPv4 라우터에 적용했다. 무효한 데이터그램은 여전히 폐기되어야 했다. 일부 부분적으로만 읽을 수 있는 경우, 라우터는 인터넷 헤더 길이(IHL)나 총 길이를 구체적으로 가리키는 파라미터 문제를 보낼 수 있었다. 이 구분은 중요했다. 수신자가 마주한 것은 잘린 프레임, 손상된 헤더, 다른 IP 버전, 또는 발신자가 불법적으로 만든 패킷일 수 있기 때문이다. 바이트 오프셋은 검증이 실패한 위치를 식별했지만, 그 바이트가 어떤 경위로 생겼는지는 결정하지 않았다.

라우터 요구사항은 ICMP 오류가 IPv4의 576바이트 최소 재조립 버퍼를 넘지 않는 한, 유발 데이터그램을 가능한 한 많이 인용할 수 있도록 허용했다. 근거 패키지는 RFC 792의 원래 페이로드 여덟 옥텟을 넘어 늘어날 수 있었지만 여전히 경계가 있었다. 진단 응답이 임의의 패킷을 무한한 응답으로 증폭할 허가는 아니었다.

IPv6는 포인터가 체인을 따라가게 했다

IPv4의 포인터는 한 옥텟을 차지했다. 옵션을 포함한 IPv4 헤더가 60바이트를 넘을 수 없었기 때문이다. IPv6는 선택적 정보의 형태를 바꾸었다. 고정된 40바이트 기본 헤더 뒤에 상위 계층 프로토콜이 나타나기 전에 순서 있는 확장 헤더 체인이 이어질 수 있었다. 첫 헤더에만 국한된 위치 메커니즘은 도달 범위와 의미 양면에서 너무 작았다.

1998년 RFC 2463의 ICMPv6 사양은 파라미터 문제(타입 4)에 32비트 포인터를 부여했다. 그 값은 유발 패킷 내의 옥텟 오프셋이 되었다. 세 가지 코드가 원인을 나누었다: 코드 0은 잘못된 헤더 필드, 코드 1은 인식할 수 없는 Next Header, 코드 2는 인식할 수 없는 IPv6 옵션이다. RFC 4443은 2006년에 이 구조를 그대로 유지했다.

표준의 예시는 이 변화를 체감하게 한다. 포인터 40과 코드 1은 40바이트 IPv6 기본 헤더 바로 다음 전이 지점에서 Next Header 값을 가리킨다. 이 숫자는 라우터 수도, 프로토콜 식별자도, 오류 심각도도 아니다. 한 파서가 다음에 무엇이 오는지 더 이상 선택할 수 없게 된 필드의 위치다.

RFC 8200은 그 근거를 순서 있는 처리와 묶는다. 목적지는 앞서 보지 않고 익숙한 헤더를 찾아 그 이전의 알 수 없는 전이가 없었던 것처럼 행세하지 않는다. 계속 진행해야 하면서 현재의 Next Header 값을 인식하지 못하면 폐기하고 그 값을 가리킨다. IPv6 옵션 타입은 별도로 코드 2와 인식되지 않은 옵션 타입을 향한 포인터를 요구할 수 있다. 그 옵션-액션 설계는 그 자체로 하나의 메커니즘이며, 여기서는 공유된 위치 계약의 또 다른 사용례로서만 중요하다.

따라서 포인터는 이해의 경계를 기록한다. 이것은 말한다: 처리가 이 바이트에 도달했고, 적용되는 규칙 아래 합법적으로 계속할 수 없었다. 그리고 노드가 도달하지 못한 바이트에 대해서는 아무것도 말하지 않는다. 패킷에는 추가 결함이 있을 수 있다. 처음 보고된 정지 지점이 체인의 나머지에 대한 증명서는 아니다.

위치가 반환된 근거를 넘어설 수 있다

ICMPv6 오류 메시지는 응답이 IPv6의 최소 MTU를 넘지 않는 한 유발 패킷을 가능한 한 많이 포함해야 한다. 이는 네트워크를 무한한 오류 트래픽으로부터 보호하고, 상위 계층이 식별용 맥락을 복원할 합리적 기회를 준다. 긴 확장 체인은 어려운 경우를 만든다: 오류가 있는 필드가 들어맞는 부분보다 뒤에 있을 수 있다.

RFC 4443은 어느 쪽도 거짓으로 만들지 않고 이 경우를 처리한다. 32비트 포인터는 ICMPv6 메시지에 담긴 유발 패킷 바이트의 끝을 넘어 가리킬 수 있다. 수신자는 응답에 그 오프셋의 옥텟이 없더라도 보고자의 오프셋을 알 수 있다.

이것은 드물게 정직한 근거 모델이다. 포인터를 마지막 반환 바이트로 고정하여 잘못된 필드를 비난하게 만들지 않는다. 응답을 크기 한계를 넘어 확장하여 진단을 증폭 메커니즘으로 만들지도 않는다. 정밀한 주장—보고자가 어디서 멈췄는가—과 명시적 부재—이름 지어진 바이트는 여기에 없다—를 나란히 보존한다.

이 부재에는 결과가 따른다. 소프트웨어는 포인터를 자동으로 안전한 배열 인덱스로 다루어서는 안 된다. 먼저 인용된 유발 패킷 버퍼가 실제로 그 오프셋에 도달하는지 검사해야 한다. 하나의 숫자가 프로토콜의 좌표 공간에서는 유효하면서 수신자의 로컬 메모리 버퍼에서는 무효할 수 있다.

인용이 상위 계층 프로토콜을 드러내기에 너무 짧을 수도 있다. RFC 4443은 관련 상위 계층 프로세스를 식별할 수 없을 때 그런 오류를 IPv6 계층 처리 후 폐기할 수 있다고 한다. 정밀한 네트워크 계층 위치가 그것을 활용할 응용까지의 전달을 보장하지는 않는다.

패킷은 잘 구성되었는데 파서가 가득 찬 경우

RFC 8883은 2020년에 같은 어휘를 확장했다. 새로운 ICMPv6 파라미터 문제 코드는 중간 노드에서의 인식 불가 Next Header와 확장 헤더 크기, 총 체인 길이, 헤더 수, 옵션 수, 개별 옵션 크기에 대한 로컬 한계를 다룬다. 코드에 따라 포인터는 그 값을, 첫 초과 옥텟을, 개수를 넘은 첫 헤더를, 또는 로컬 한계를 넘은 첫 옵션을 가리킨다.

이것은 파라미터 문제가 진실하게 의미할 수 있는 범위를 바꾸었다. 패킷에 기형적인 문법이 없을 수도 있다. 구조는 올바르지만 노드가 수행할 의사가 있는 파싱 작업보다 많은 작업을 요구할 수 있다. 코드는 로컬 경계의 종류를 전달하고, 포인터는 그 경계가 어디서 넘어졌는지 위치를 정한다.

이 구분은 로컬 구현 한계가 보편적 무효성으로 위장하는 것을 막는다. 다른 노드는 같은 체인을 받아들일 수 있다. 반대로 표준에 부합하는 형식이 모든 포워딩 장치에 무한한 파싱 자원 할당을 강요하지도 않는다. 상호운용성은 거부를 알아볼 수 있게 만들면서도, 한 노드의 용량이 패킷의 전역 속성인 것처럼 꾸미지 않는 데 달려 있다.

RFC 8883은 메모리 안전 교훈을 명시한다. 포인터로 반환된 유발 패킷 데이터를 읽기 전에, 구현은 오프셋이 이용 가능한 인용 길이보다 작음을 검증해야 한다. 와이어상의 정밀성이 메모리 속 바이트의 소유권은 아니다.

자동 권위가 없는 근거

ICMP 오류는 보고 노드의 주장이다. 기본적으로 인증되지 않는다. RFC 4443은 위조된 출처, 변경된 메시지 필드, 서비스 거부, 상위 계층 반응을 겨냥한 공격을 논의한다. 상위 계층이 행동하기 전에 인용된 맥락을 검증할 것을 권고한다. 상관 분석은 주소, 프로토콜 필드, 포트, 최근 트래픽이 실제 전송된 것과 일치하는지 물을 수 있다. 그래도 메시지를 경로에 대한 완전한 기술로 바꾸지는 못한다.

속도 제한은 또 다른 비대칭을 더한다. IPv6 노드는 자신이 발생시키는 오류를 제한해야 한다. 그렇지 않으면 잘못된 패킷의 스트림이 대역폭과 처리 능력을 소모할 수 있기 때문이다. 멀티캐스트와 발신 주소 규칙은 다른 응답을 억제한다. 미들박스는 ICMP를 필터링할 수 있다. 따라서 파라미터 문제 메시지는 어느 보고자가 그것을 만들었다는 사실은 증명할 수 있지만, 모든 노드가 패킷을 성공적으로 파싱했다는 것은 부재로 증명할 수 없다.

역사적 성취는 완벽한 진단이 아니었다. 그것은 동작, 원인, 위치, 맥락의 규율 있는 분리였다. 패킷은 폐기되었다. 코드는 처리가 왜 멈췄는지 분류했다. 포인터는 감지된 경계의 위치를 정했다. 인용은 들어맞는 맥락만을 반환했다. 각 사실은 서로 다른 소유자와 서로 다른 한계를 가졌다.

그 구조는 분산 시스템에 대한 일반적 교훈을 여전히 준다. 작업을 거부해야 할 때, 원점이 실패를 찾을 수 있게 하는 가장 작은 좌표를 보고하라. 반환된 근거를 명시된 자원 경계 안에 두라. 정밀한 숫자를 완전한 지식의 주장으로 바꾸지 말라.

출처