요약

  • RFC 733부터 메시지 식별자를 생성하는 시스템은 그 식별자를 고유하게 만들어야 했습니다. 개정판에는 새 ID가 부여되며, 전송 계층이 추가한 추적 필드가 원래의 신원을 반드시 바꾸는 것은 아니었습니다.
  • In-Reply-To와References는 식별자를 대화 그래프로 바꾸었습니다. Netnews는 더 나아가 각 서버가 본 ID를 기억하고 중복을 폐기하여, 복제되는 배포 시스템이 루프를 로컬에서 종료할 수 있게 했습니다.
  • 이 이름은 서명이나 콘텐츠 해시가 결코 아니었습니다. Netnews는 본문이 달라도 동일한 ID를 하나의 기사로 취급하기로 의도적으로 정했으므로, 예측 가능한 충돌은 의도된 기사를 가려버릴 수 있었습니다.

바이트는 바뀌어도 메시지는 바뀌지 않았다

메시지가 전송 계층에 들어가는 상상을 해봅시다. 다음 릴레이는Received필드를 앞에 덧붙입니다. 저장된 바이트는 더 이상 제출된 바이트와 동일하지 않지만, 릴레이는 개정판을 작성한 것이 아닙니다. 원래의Message-ID는 그대로 남습니다.

이번에는 작성자가 메시지가 전달하는 명제를 바꾸고 그 개정을 새 메시지로 발행한다고 상상해봅시다. 텍스트의 상당 부분이 동일할 수 있지만, 신원은 바뀌어야 합니다. 이것이 1977년RFC 733이 그은 경계였습니다. 식별자는 정확히 하나의 버전 또는 인스턴스를 가리키며, 이후 개정판에는 새 식별자가 부여되어야 합니다. 고유성은 중앙 레지스트리가 아니라 이름을 생성하는 호스트가 보장했습니다.

RFC 822는 이 규칙을 1982년 인터넷 메시지 형식으로 가져왔습니다. 이 필드는 사람이 읽는 의미가 아니라 기계를 위한 것이었습니다. 그 목적은 제목을 요약하거나 사람을 식별하는 것이 아니었습니다. 선언된 하나의 메시지 버전에 안정적인 핸들을 공급하는 것이었습니다.

이 정의는 두 가지 쉬운 극단을 모두 피했습니다. 신원은 어느 홉에 우연히 저장된 바이트 열이 아니었고, 아이디어의 모든 개정판에 영속적인 신원을 부여하는 것도 아니었습니다. 작성하는 쪽이 인스턴스를 선언하고, 다른 시스템은 그 이름을 보존하고 참조했습니다.

로컬에서 조립된 전역 이름

RFC 5322의 현대 규칙은 명시적입니다. 메시지 식별자는 전역적으로 고유해야 하며, 생성자가 이를 보장해야 합니다. 그러나 표준은 한 번에 하나의 ID를 할당하는 기구를 정의하지 않습니다.

대신 나뉜 이름공간을 권장합니다. 도메인 식별자는@오른쪽에 속하고, 왼쪽에는 생성자가 그 범위 안에서 고유하게 유지할 수 있는 값, 예를 들어 시각과 일련번호 또는 프로세스별 값을 조합한 값을 둡니다. 전역적으로 인식 가능한 범위에 로컬 장부 기록을 더하면 전역 트랜잭션 없이 전역 이름이 만들어집니다.

주소와의 유사성은 유용하지만 한계가 있습니다. 오른쪽은 책임을 분할하는 데 도움을 줍니다. 하지만 식별자를 메일함으로 만들거나, 오늘 resolve되도록 요구하거나, 작성자를 인증하거나, 도메인에 대한 통제권을 증명하지는 않습니다. 받는 쪽도 왼쪽에서 숨은 비즈니스 의미를 추론해서는 안 됩니다.

같은 RFC는 의미 경계를 유난히 명확하게 만듭니다. 추적 또는 resent 필드를 추가하는 것은 구문을 바꾸면서도 새 메시지를 만들지 않을 수 있습니다. ID가 바뀌는지는 발신자의 의도된 의미—이것이 같은 메시지인지 다른 메시지인지—가 결정합니다. 따라서Message-ID는 체크섬도 SMTP 전송 식별자도 아닙니다.

답장은 간선이 되었다

안정적인 이름은 다른 객체가 그것을 가리킬 수 있을 때 더 큰 가치를 지닙니다.In-Reply-To는 부모 메시지의 ID를 전달하고,References는 부모의 이전 조상들과 이어서 부모 자신의 ID를 전달합니다. 소프트웨어는 그 순서를 사용해 메시지가 서로 다른 경로나 시각에 도착했더라도 스레드를 표시할 수 있습니다.

이 그래프는 현대 메일 클라이언트를 위해서만 발명된 것이 아니었습니다. 1983년 Usenet 교환 표준인RFC 850은 후속 기사가 원래 기사의 References를 확장하도록 요구했습니다. 그리고 운영상의 목적을 밝혔습니다. 리더 소프트웨어는 기사를 대화로 묶을 수 있고, 독자는 뉴스그룹 전체를 떠나지 않고 하나의 대화를 무시할 수 있습니다.

그래프에도 한계가 있습니다.RFC 5322는 소프트웨어가 거슬러 올라갈 때 단일 부모를 가정하는 경우가 많다고 지적합니다. 다중 부모 구조는 완전히 정의되어 있지 않습니다. References 체인은 선언된 조상을 기록할 뿐, 답장이 부모를 이해했거나 인용했거나 부모의 저자가 썼다는 것을 증명하지 않습니다.

식별자는 모든 서버의 기억이 되었다

Usenet은 Message-ID를 배포 제어의 일부로 만들었습니다. 피어 사이의 플러드에서 서버는 같은 기사를 둘 이상의 방향으로 받을 수 있습니다. 모든 도착을 다시 전달하면 사이클이 무한히 돌 수 있습니다.

RFC 1036은 히스토리 메커니즘을 기술합니다. 각 호스트는 자신이 본 기사를 Message-ID로 추적합니다. 그 ID가 다시 도착하면 호스트는 들어온 사본을 즉시 폐기합니다.Path필드는 이미 알려진 이전 홉으로의 불필요한 전송을 막을 수 있지만, 루프를 멈추는 데는 로컬 히스토리만으로 충분합니다.

이것이 분산형 수렴입니다. 마스터 서버는 어디에도 기사의 전역적 완료를 표시하지 않습니다. 각 사이트는 하나의 이름을 자신의 기억과 비교하고, 이미 그 논리적 기사를 수용했음을 스스로 판단합니다. 인간의 대화를 지탱하던 바로 그 필드가 분산 중복 억제를 위한 간결한 키가 된 것입니다.

같은 이름이 다른 본문을 눌렀을 때

RFC 5536은 이 트레이드오프를 뚜렷하게 만듭니다. Netnews는 본문이나 헤더가 달라도 Message-ID가 같은 기사를 같은 기사로 취급합니다. 서버가 ID를 옥텟 단위로 빠르고 일관되게 비교할 수 있도록 구문을 좁히고, 길이를 제한하고, 대소문자를 보존합니다. 또한 고유성이 이 식별자를 사용하는 프로토콜, 특히 전자메일과 Netnews에 걸쳐 있음을 밝힙니다.

이 규칙은 전파를 다루기 쉽게 만들지만, 충돌을 권위로 바꿉니다. 공격자가 미래 기사의 ID를 예측하여 그 ID를 가진 다른 기사를 먼저 게시하면, 서버는 의도된 기사를 이미 본 것으로 거부할 수 있습니다. 그래서 RFC 5536은 예측 불가능성을 권장합니다. 위험은 깨진 콘텐츠 다이제스트가 아니었습니다—다이제스트 자체가 없었으니까요. 위험은 거짓 주장이 분산된 이름 장부에 먼저 들어가는 것이었습니다.

이 이름이 증명하지 않은 것

Message-ID는 신뢰가 아니라 참조를 해결합니다. 본문에 서명하지 않고, From 필드를 인증하지 않고, SMTP 봉투 트랜잭션을 식별하지 않고, 독자가 메시지를 보았다는 것을 증명하지 않으며, 두 사본이 동일한 바이트를 담고 있다는 보장도 하지 않습니다. 동일한 ID는 충돌을 숨길 수 있고, 다른 ID는 동일한 텍스트를 담을 수 있습니다.

이 겸손함이 설계가 오래도록 유지된 이유입니다. 원본은 이름 지정을 소유하고, 전송 계층은 이름을 바꾸지 않으면서 소관 증거를 추가할 수 있으며, 메일 소프트웨어는 답장 간선을 소유하고, 뉴스 서버는 로컬 히스토리와 충돌 처리를 소유합니다. 암호학적 증명은 다른 계층의 몫입니다.

출처와 한계

역사적 계보는RFC 733,RFC 822,RFC 850,RFC 1036,RFC 2822,RFC 5322,RFC 5536입니다. 이 문서들은 형식과 인지된 실패 양상을 확립합니다. 그러나 현재의 충돌률, 공급자의 알고리즘, 구현 점유율 또는 보존 기간을 측정하지는 않습니다.