요약

  • RFC 1301은 MTP 마스터가 메시지의 종료 마커와 그 사이의 모든 패킷을 확인한 뒤 해당 메시지를 accepted로 표시하고, accepted·pending·rejected 상태를 순환하는 12개 메시지 벡터로 배포하도록 했다.
  • MTP는 최선형(best-effort) 멀티캐스트 위에서 동작했으며, 전송 토큰, 하트비트, 윈도, 보존, NAK, 중복 억제를 사용했고, 성공한 소비자로부터는 평소 긍정 확인을 받지 못했다.
  • accepted는 정의된 전송 계약이었지, 모든 소비자 애플리케이션이 바이트를 해석했고, 동작을 승인했고, 상태를 변경했고, 운영 결과를 전달했다는 증명이 아니었다.

판정은 다음 패킷을 타고 이동했다

RFC 1301은 신뢰성을 개별 전달 영수증의 나열로 설계하지 않았다. 새 패킷이 이전 메시지들에 대한 결정을 실어 나르는 지속적인 대화로 설계했다. 메시지 수락 기록은 동기화 플래그, 메시지 시퀀스 번호, 패킷 시퀀스 번호, 그리고 2비트짜리 간결한 상태 벡터를 담았다. 12개의 위치가 바로 앞선 12개 메시지를 서술했다. 프로세스는 그룹이 계속 진행되는 동안 이전 메시지가 accepted가 되었는지, pending으로 남았는지, rejected로 처리되었는지 알 수 있었다.

헤더 공간이 부족한 상황에서 이것은 영리한 활용이다. 동시에 후대 역사가에게 경고이기도 하다. accepted라는 값은 그 결정 주체, 입력, 보존 기간이 명시된 후에만 의미를 갖는다. MTP에서 결정 주체는 마스터였다. 마스터는 모든 애플리케이션으로부터 서명된 성공 진술을 수집하지 않았다. 전송 교환을 관찰하고 프로토콜의 규칙을 적용했다.

이 구분이 그 상태를 약하거나 거짓으로 만들지는 않는다. RFC 1301 안에서 accepted는 권위 있는 전송 결과였다. 오류는 수집자가 질문을 조용히 바꿀 때 시작된다. “MTP 마스터가 이 메시지에 대해 무엇을 결정했는가?”라는 질문은 “모든 수신 애플리케이션이 그 메시지로 무엇을 했는가?”와 같지 않다.

최선형 멀티캐스트는 바닥을 제공했지 보장을 제공하지 않았다

RFC 1112는 IP 멀티캐스트를, 구성원이 바뀔 수 있는 호스트 그룹에 하나의 데이터그램을 보내는 것으로 정의했다. 그 신뢰성은 일반 IP 데이터그램에 제공되는 것과 같은 최선형이었다. 데이터그램이 모든 구성원에게 손상 없이 도착하거나, 이웃과 같은 순서로 도착한다는 보장은 없었다. 그룹 주소는 전달 집합을 이름으로 지정했을 뿐, 그룹 합의를 제공하지 않았다.

MTP는 그 기반 위에 결여된 전송 기구를 만들려 했다. RFC 1301은 협력하는 프로세스 집합을 웹(web)이라 불렀다. 한 프로세스는 마스터여야 했다. 다른 구성원은 생산자-소비자 또는 순수 소비자였다. 마스터는 웹을 인스턴스화하고, 구성원과 성능 매개변수를 제어하고, 전송 토큰을 할당했다. 생산자는 원할 때마다 일반 클라이언트 데이터를 멀티캐스트할 수 없었다. 먼저 다음 메시지 시퀀스 번호를 담은 토큰을 획득해야 했다.

이 배치는 네트워크 복제와 전송 순서를 분리했다. IP가 데이터그램을 분배할 수 있었다. 마스터는 메시지를 생산할 권한을 직렬화했고, 수락 기록이 공통 결정을 가시화했다. 어느 계층도 애플리케이션의 데이터를 해석하지 않았다.

성공한 소비자는 평소 침묵했다

MTP는 부정 확인(NAK) 프로토콜이었다. 누락된 데이터를 감지한 소비자는 NAK를 보냈다. 기대한 것을 본 소비자는 생산자에게 긍정적 성공 표시를 보내지 않았다. RFC 1301은 역방향 트래픽을 줄이기 위해 이 침묵을 명시적으로 활용했다.

따라서 침묵에는 프로토콜적 의미가 있었지만, 조건부 의미였다. 그것은 관련 상태 및 타이밍 가정 안에서 복구 가능한 결손이 이 소비자로 하여금 NAK를 발행하게 하지 않았다는 뜻이었다. 소비자가 영원히 존재했다거나, 그 애플리케이션이 메시지를 해석했다거나, 사용자가 그것을 보았다거나, 외부 효과가 발생했다는 지속적 진술이 아니었다.

이 절충은 멀티캐스트 확장의 핵심이었다. 큰 그룹으로 가는 모든 패킷마다 모든 수신자가 확인을 보낸다면 역방향 트래픽이 유용한 전송을 압도할 수 있었다. NAK는 트래픽을 예외에 집중시켰다. 대가는 증거의 비대칭이었다. 실패는 명시적 패킷이 될 수 있었지만, 평범한 성공은 계속되는 프로토콜 동작으로부터 추론되었다.

accepted는 마스터가 완전한 메시지를 보았다는 뜻이었다

RFC 1301의 규칙은 정밀했다. 마스터가data[eom]과 그 사이의 모든 패킷을 보았다면 메시지를 accepted로 표시했다. 메시지가 불완전하지만 마스터가 송신자가 여전히 동작 중이며 연결되어 있다고 믿었다면 pending으로 표시했다. 메시지가 불완전하고 송신자가 실패했거나 분리된 것으로 보이면 rejected로 표시했다.

이 상태들은 관찰과 판단을 결합했다. 마스터에서의 완전성이 수락을 만들었다. 불완전성에 생존 판단이 더해지면 pending 또는 rejected가 되었다. 한 구성원의 패킷 추적은 마스터가 그 결정에 이르게 한 모든 관찰을 보여주지 않고도 공표된 결과를 보여줄 수 있었다. 따라서 후속 감사는 결정과 그 출처를 모두 필요로 한다. 마스터가 무엇을 받았는지, 어느 종료 마커를 그 시퀀스와 연결했는지, 생산자가 여전히 연결되어 있다고 혹은 사라졌다고 믿은 이유가 무엇인지가 그것이다.

이 규칙은 accepted가 애플리케이션 판정이 아니었던 이유도 드러낸다. 마스터에게 필요한 것은 바이트와 그 종료 마커였다. 그 바이트를 이해할 필요는 없었다. RFC 1301은 클라이언트 데이터를 해석되지 않는 것으로 묘사했다. 완벽하게 수락된 메시지에 잘못된 명령, 중복된 업무 지시, 낡은 문서, 또는 애플리케이션이 의도적으로 무시한 데이터가 들어 있을 수 있었다.

12개 위치가 메모리와 진행을 한정했다

이 벡터는 이동하는 창이었다. 메시지m의 토큰이 전송될 때 그 첫 번째 위치는m − 1을, 두 번째는m − 2를, 이런 식으로 서술했다. 오래된 상태는 결국 밀려나갔다. RFC 1301은 이 헤더를 영구 장부로 가장하지 않았다.

다만 이 프로토콜은 미해결 상태가 조용히 지워지는 것을 막았다. 상태를 바꿀 수 있는 것은 오직 마스터뿐이었고, 마스터는 pending 메시지를 벡터의 마지막 위치 너머로 밀어낼 수 없었다. 가장 오래된 가시 메시지가 여전히 pending이라면, 마스터는 그 메시지를 accepted 또는 rejected로 표시할 수 있을 때까지 새 토큰 요청 확인을 중단해야 했다.

이 역압은 불확실성을 운영 가능하게 만들었다. 그룹은 미해결 결정을 자신의 메모리 지평선 너머로 밀어냄으로써 진행되는 듯한 모습을 유지할 수 없었다. 그러나 최종 상태가 정상적으로 밀려나간 뒤에는 프로토콜 헤더가 더 이상 그것을 실어 나르지 않았다. 현재 벡터만 저장하는 기록 보관소는 결국 그룹이 한때 합의했던 것을 잊게 된다. 지속 가능한 역사에는 별도의 기록이 필요하다.

메시지 번호는 마스터가 제어하는 16비트 값이었다. 토큰을 승인하면 번호 하나가 소비되었고, 그에 연관된 메시지는 결국 accepted 또는 rejected에 도달해야 했다. 이는 프로토콜 시대와 순서를 확립했다. 그러나 애플리케이션의 행위에 대한 불변의 전역 식별자를 만들지는 않았다.

토큰 확인 자체에 모호성이 담겨 있었다

제어 패킷은 일반 시퀀스 번호를 소비하지 않았으므로, 반복된 토큰 요청은 스스로를 설명해주지 않았다. 마스터가 토큰을 승인했지만 그 아래에서 데이터를 관찰하지 못했다면, 반복 요청은 생산자가 확인을 놓쳤다는 뜻일 수 있었다. 혹은 생산자가 마스터가 놓친 데이터를 보냈을 수도 있었다. 재시도가 원래의 확인을 전송 중에 추월했을 가능성도 있었다.

RFC 1301은 명시적 가정을 두었다. 유니캐스트 토큰 확인 하나를 놓치는 것이, 의도적으로 여러 패킷으로 나뉜 메시지의 모든 패킷을 마스터가 놓치는 것보다 더 가능성이 높다고 간주했다. 마스터는 보류 중인 토큰을 재할당할 수 있었다. 중복 토큰 확인을 받은 생산자는 그것을 NAK처럼 취급하고 해당 메시지 번호 아래 이미 보낸 데이터를 재전송했다. 더 이상 토큰이 필요 없으면empty[cancel]로 반납했다.

이것은 산문 속에 숨겨진 결함이 아니었다. 모호한 증거에 대한 프로토콜의 대응이었다. 재시도는 어느 패킷이 손실되었는지에 대한 증명이 아니라 복구 지시를 실었다. 건전한 로그는 요청, 각 확인, 마스터의 관찰 상태, 재전송을 서로 분리해 보관하며, 이것들을 하나의 확실한 이야기로 다시 쓰지 않는다.

하트비트, 윈도, 보존이 복구의 대가를 정했다

세 공유 매개변수가 웹을 형성했다. 하트비트는 시간 리듬을 정했다. 윈도는 생산자가 한 하트비트 동안 멀티캐스트할 수 있는 새 데이터 및 재전송 데이터 패킷 수를 제한했다. 보존은 전송된 데이터와 복구 상태가 몇 개의 하트비트 간격 동안 사용 가능해야 하는지 정했다.

생산자가 패킷 하나를 채울 만큼의 클라이언트 데이터가 없지만 여전히 활동 의무가 남아 있으면empty[dally]를 보냈다. 짧은 메시지는 최소한 보존 개수를 채울 때까지 빈 패킷으로 덧대어졌다. 그 목적은 소비자가 적어도 하나의 패킷을 관찰하고 생산자를 식별할 가능성을 높이는 것이었다. 이것은 반복을 통해 공학된 확률이지, 모든 목적지로부터의 영수증이 아니었다.

소비자는 패킷 시퀀스 번호의 결손을, 혹은 완성되지 않은 조각 뒤에 하트비트 하나를 넘는 침묵이 이어지는 것을 알아챌 수 있었다. 그러면 누락된 범위를 나열한 유니캐스트 NAK를 보냈다. 생산자는 요청된 패킷을 불평한 소비자가 단 하나뿐이더라도 웹 전체에 멀티캐스트했다. 이 재전송은 윈도의 일부를 소모했고 새 데이터보다 우선순위를 가졌다. 다른 소비자들은 그 결과 생긴 중복을 폐기해야 했다.

요청된 데이터가 이미 보존 기간을 벗어났다면 생산자는nak[deny]를 반환했다. 수신자는 그 클라이언트에 실패를 보고하고 웹에서 탈퇴할 수 있었다. 복구에는 유한한 증거 지평선이 있었다. 데이터가 보존되어 있는 동안 결손은 복구될 수 있었고, 해제된 후에는 프로토콜이 할 수 있는 것은 실패의 명명뿐이었다.

인터넷 매핑이 또 하나의 경계를 더했다

IP 위의 MTP는 멀티캐스트 송수신을 위해 RFC 1112 레벨 2 지원을 필요로 했다. RFC 1301은 영구 호스트 그룹224.0.1.9를 할당했다. IP 자체는 프로세스 포트를 제공하지 않았으므로, 이 규격은 소스 포트, 목적지 포트, 길이, 선택적 체크섬을 담은 브리지 헤더를 IP 프로토콜 번호 92 아래에 실었다.

이 식별자들은 전송 인스턴스의 위치를 정했다. 구성원을 인증하지는 않았다. 이 메모의 보안 절은 보안이 논의되지 않았다고 밝혔다. TSAP, 연결 식별자, 토큰, 마스터 역할은 프로세스를 제어하는 사람이 누구인지, 그 행위가 조직을 대신할 권한이 있는지를 증명하지 않으면서 프로토콜 라우팅과 상태를 지원할 수 있었다.

후속 검토가 집중된 제어의 비용을 드러냈다

RFC 1458은 대규모 이미지 배포 작업을 고려하면서 MTP를 다시 살폈다. 이 검토는 마스터, 전송 토큰 기반 속도 제어, 선택적 NAK 복구, 중복 처리를 인정했다. 동시에 외부 그룹 주소와 식별자에 대한 의존, 그리고 거의 모든 제어 트래픽이 마스터를 통과할 때 생기는 지연과 혼잡을 지적했다. 저자들은 그 작업 부하에 대해 MTP가 부적합하다고 판정했다.

이 검토가 RFC 1301의 의미론을 취소하는 것은 아니다. 합의 기구에는 제어 위상과 작업 부하 한계도 있다는 것을 보여줄 뿐이다. 순서를 명시적으로 만들던 그 마스터가 병목이 될 수 있었다. 평범한 역방향 트래픽을 아껴주던 그 NAK 경제가 잃지 않은 구성원에게까지 복구 데이터를 멀티캐스트할 수 있었다.

출처

이 출처들은 프로토콜 정의와 후속 설계 검토를 확립한다. 살아 있는 MTP 웹, 수신자 모수, 인증된 구성원, 애플리케이션 행위, 사고, 도입 수준, 현재 배포 현황 중 어느 것도 확립하지 않는다.