요약

  • RFC 3208은 수신자별 긍정 확인 응답을 선택적 NAK로 대체했다. 각 NAK는 홉 단위로 확인되었고, 라우터는 손실이 보고된 하류 지점(브랜치)을 기록했다.
  • NAK 확인(NCF)은 복구 요청이 역방향 경로의 한 지점에서 처리되었음을 증명했다. RDATA가 발송되었거나, 요청한 수신자에게 도달했거나, 패킷이 복원되었거나, 알 수 없는 그룹에 대한 전달이 완료되었음을 증명하지는 않았다.

신뢰할 수 있는 전달은 흔히 쌓여가는 영수증 더미로 상상하기 쉽다. 송신자 하나, 수신자 하나, 확인 응답 하나: 송신자는 상대 끝단이 도착했다고 말할 때까지 패킷을 보관할 수 있다. 멀티캐스트는 이 산술을 스스로에게 불리하게 만들었다. 하나의 전송에 수천 명의 수신자가 있고 성공한 패킷마다 수천 건의 긍정 확인 응답이 발생한다면, 성공의 증거가 그것이 보호하려던 시스템 자체를 잠식해버릴 수 있었다.

RFC 3208의 PGM(Pragmatic General Multicast, 실용적 범용 멀티캐스트)은 정반대의 길을 갔다. 긍정 확인 응답을 폐지한 것이다. 소스는 순서가 매겨진 ODATA(Original Data) 패킷을 전송했다. 수신자는 시퀀스를 관찰하다가 무언가 빠지면 말을 했다. 선택적 부정 확인 응답(NAK)이 복구를 요청했다. 침묵은 관측된 갭이 이 장치를 통해 피드백을 만들지 않았다는 뜻이었지, 수신자를 열거하거나 그들의 애플리케이션을 인증해주지는 않았다.

그 결정이 PGM이 약속할 수 있는 범위를 규정했다. 그룹 멤버십 모델이 없었다. 멤버는 소스가 알지 못한 채 가입하고 떠날 수 있었다. 알려진 수신자 집합에 대한 확인된 전달이나 복수 소스 간 전체 순서를 요구하는 애플리케이션은 대상이 아니었다. 소스의 이동하는 전송 윈도우 내에서 각 수신자는 패킷을 원본 전송과 복구를 통해 얻거나, 복구 불가능한 손실을 감지했다.

문법이 중요하다. 그 보장은 소스의 보편적 대장이 아니라 개별 수신자의 것이었다. 수신자는 모든 패킷을 갖고 있거나 복구가 불가능해졌다는 사실을 알 수 있었다. 그렇다고 소스가 모두에 대한 하나의 권위적 진술을 갖는 것은 아니었다.

수신자가 시퀀스 갭을 감지하면 NAK를 추상적인 글로벌 소스로 곧장 보내지 않았다. 소스의 배포 트리에서 자신의 마지막 홉 PGM 네트워크 요소로 요청을 유니캐스트했다. 수신자는 그 네트워크 요소가 수신 인터페이스에서 일치하는 NAK 확인(NCF)을 멀티캐스트할 때까지 NAK를 반복했다.

네트워크 요소는 그 NAK를 다음 상류 PGM 요소로 전달하고 그 상류 요소가 자체 NCF를 돌려줄 때까지 반복했다. 절차는 소스가 요청을 접수하고 확인할 때까지 홉 단위로 계속되었다. NCF는 중요한 곳에서 멀티캐스트되었지만, PGM 라우터는 NCF를 종단 간 성공 메시지로 전파하지 않았다.

이로써 정밀한 영수증이 만들어졌다. NCF는 “이 홉에서 부정 요청이 관측되어 다음 단계로 넘겨졌다”고 말했다. “빠진 패킷이 재전송되었다”고 말하지 않았다. “재전송이 필요한 모든 브랜치를 따랐다”고 말하지 않았다. “수신자가 이를 받아들였다”고도 말하지 않았다. 그 사실들은 이후의 행동과 이후의 관측에 속했다.

이 구분은 구조적이었다. 네트워크 요소가 NAK를 받으면 복구 상태를 기록했다: 전송 세션, 빠진 시퀀스 번호, 요청이 도착한 인터페이스. 상류 NCF 이후 요소는 복구가 올 때까지 NAK 패킷을 보존하지 않았다. 요청을 폐기했다. 이후 RDATA로 이어지는 지속적인 다리는 복구 상태이며, 확인 응답도 원래 NAK 객체도 아니었다.

복구 데이터(RDATA)는 원본 소스에서 오거나 DLR(Designated Local Repairer, 지정 로컬 복구자)에서 올 수 있었다. 라우터는 손실이 기록된 인터페이스로만 그 복구를 전달했다. 이는 재전송을 요청한 브랜치로 재전송을 제한하여, 멀티캐스트 그룹 전체를 다시 범람시키지 않았다.

기본값은 의도적으로 엄격했다. 일치하는 복구 상태가 없으면 PGM 네트워크 요소는 RDATA를 전달하지 않았다. 역방향 요청 경로가 필요한 하류 상태를 설치하지 못했다면, 복구가 상류에 존재하더라도 수신자에게 도달하지 못할 수 있었다. 패킷의 존재와 그 패킷이 한 인터페이스를 통과할 권한은 별개의 사실이었다.

라우터는 어느 방향이 소스로 돌아가는 방향인지 어떻게 알았는가? PGM 소스는 SPM(Source Path Message, 소스 경로 메시지)을 데이터와 인터리브해서 전송했다. 각 PGM 요소는 그 소스의 배포 트리에서 상류 이웃을 식별하도록 경로 주소를 재작성했다. 수신자는 그 결과로 만들어진 경로 상태를 사용해 NAK의 주소를 지정했다. 라우터는 이를 사용해 ODATA 경로의 역방향으로 요청을 릴레이했다.

SPM은 소스 전송 윈도우의 후미(trailing edge)와 전두(leading edge)도 광고했다. 그 윈도우가 복구에 사용 가능한 범위를 한정했다. 수신자가 패킷이 후미를 벗어난 뒤에야 손실을 발견했다면, 다른 NAK가 소스나 DLR이 더 이상 보유하지 않은 바이트를 만들어낼 수는 없었다. 실패는 감지 가능해질 수 있었지만 복구 가능해지지는 않았다.

PGM은 부정 피드백이 유일한 복구 트리거였기 때문에 부정 피드백을 강화했다. 소스는 데이터가 조용할 때에도 주기적으로 SPM을 보내 수신자가 갭을 알아차릴 기회를 새로 주고 윈도우 정보를 갱신했다. 수신자는 재시도 타이머를 사용했다. 확인되었지만 RDATA가 없는 요청은 완료로 처리되지 않고 또 다른 복구 주기로 이어질 수 있었다.

동시에 PGM은 부정적 증거가 함몰되지 않도록 해야 했다. 수신자들이 같은 ODATA 패킷을 모두 놓칠 수 있었다. 각자 NAK를 보내기 전 무작위 백오프를 시작했다. 그 동안 일치하는 NCF나 로컬 NAK를 들으면 자신의 요청을 억제하고 보낸 것처럼 행동했다. 라우터도 해당 손실에 대한 복구 상태가 있으면 중복 NAK를 제거했다.

통상의 결과는 많은 수신자가 놓친 패킷 하나에 대해 소스 쪽으로 돌아가는 단일 NAK였다. 그것이 확장성의 승리였다. 동시에 증거의 압축이기도 했다. 하나의 NAK가 미지수의 억제된 관측을 대표할 수 있었다. NCF는 개별적으로 요청을 보낸 적 없는 수신자들을 조용히 시킬 수 있었다. 어느 패킷도 수신자 명단이 아니었다.

복구 서브트리 역시 투영이었다. 인터페이스 목록은 부정적 증거가 어디 도착했는지 말해줄 뿐, 인터페이스 뒤의 수신자 수를 세거나 한 수신자와 백 명을 구분하거나 복구가 돌아올 때 모든 호스트가 여전히 참여 중임을 증명하지 않았다. 시도된 복구를 라우팅하기에 충분한 상태였지 인구조사는 아니었다.

DLR은 전송 세션 신원을 바꾸지 않은 채 RDATA의 물리적 출처를 바꿨다. DLR은 복구에 원본 소스의 TSI(전송 세션 식별자)를 사용했다. 이 연속성 덕에 수신자는 패킷을 올바른 시퀀스에 놓을 수 있었지만, 원본 소스가 복구를 발송했다는 뜻은 아니었다. 세션 신원, 복구 소유권, 패킷 출처는 감사에서 분리된 상태로 유지되어야 했다.

PGM은 DLR 발견과 리다이렉션까지 허용했고, 결과로 오해될 수 있는 영수증을 더 늘렸다. 리다이렉트는 수신자나 라우터에게 복구 요청을 어디로 보낼지 알려줄 수 있었다. 폴 응답은 복구자의 가용성을 알릴 수 있었다. 이 메시지들은 가능한 제어 경로를 확립했을 뿐, 복구자가 패킷을 보유하고 있거나 이후 RDATA가 목적지에 도달했음을 증명하지 않았다.

전송 윈도우는 소스의 로컬 정책을 드러냈다. 데이터 기반 전략에서는 후미 근처 데이터에 대한 NAK가 윈도우 진행을 지연시킬 수 있었다. 소스는 지연을 감수하고 완전성을 우선했다. 시간 기반 전략에서는 미처리 NAK를 기다리지 않고 윈도우가 실시간으로 진행되어, 복구 불가능한 손실 가능성을 감수하고 처리량과 적시성을 지켰다.

이는 신뢰성의 두 가지 철자가 아니었다. 소스가 무엇을 얼마나 오래 보유하려 하는지에 대한 서로 다른 결정을 담고 있었다. 어느 전략에서든 NCF의 의미는 동일하게 제한적이었고, 이후 복구가 가능할 확률은 윈도우 정책에 달렸다.

FEC(전방 오류 정정)는 복구의 형태를 바꿨지만 증거 사슬을 바꾸지는 않았다. 복구는 빠진 패킷의 복사본일 수도 있고 수신자가 데이터를 재구성할 수 있는 패리티 패킷일 수도 있었다. 패리티 NCF는 일정 수의 패리티 패킷에 대한 요청을 확인할 수 있었다. 수신자는 여전히 충분한 복구 패킷을 기다려야 했고 디코딩해야 했다. 요청한 개수에 대한 확인이 성공적 재구성에 대한 확인은 아니었다.

PGM의 실험적(Experimental) 지위는 장식이 아니었다. 적용 가능성 진술은 혼잡 제어, 라우터 지원, 로컬 재전송, 프로그래밍 API를 프로토타입적 요소로 불렀다. RFC 2357은 이미 신뢰할 수 있는 멀티캐스트 제안이 다루어야 할 기준, 특히 혼잡 책임을 서술했다. RFC 3208은 하나의 거대한 작동하는 설계 공간을 제공했을 뿐, 모든 메커니즘이 배포된 표준 서비스가 되었음의 증명은 아니었다.

보안 절은 상태 보유형 지원의 대가를 명확히 했다. 위조 SPM은 NAK를 잘못된 방향으로 보낼 수 있었다. 위조 NAK는 가짜 복구 상태로 메모리를 소진할 수 있었다. 위조 NCF는 상류 요청 전달을 너무 이르게 멈출 수 있었다. 위조 RDATA는 정당한 복구 상태를 파괴하고 실제 복구가 브랜치를 통과하지 못하게 만들 수 있었다.

공격은 프로토콜의 증거 변환을 따랐다. 제어 패킷은 애플리케이션 내용을 손상시키지 않고도 손실 발생 위치, 요청이 여전히 미처리인지, 어느 인터페이스가 복구를 받을 자격이 있는지에 대한 기록을 손상시킬 수 있었다. 이웃한 소스, 수신자, 라우터, DLR의 전면 인증은 단순한 메시지 시퀀스를 넘어서는 일이었다.

그래서 NCF를 전달 옆의 체크 표시로 그려서는 안 된다. NCF는 NAK가 사라지지 않게 만드는 메커니즘 안의 한정된 확인 응답이었다. 그 가치는 덜 말하는 데서 왔다: 이 요청이 여기서 들렸다는 것. 나머지는 RDATA, 수신자 상태, 애플리케이션 상태가 말해야 했다.