요약

  • RTSP의 성공적인 SETUP은 서버 측 제어 컨텍스트를 생성하고 세션 식별자를 반환했다. SDP 설명이나 열려 있는 TCP 연결은 어느 쪽도 그렇게 하지 않았다.
  • 그 컨텍스트는 제어 연결이 교체되더라도 살아남을 수 있었지만, 식별자는 올바른 URI, 메서드 상태, 인증 또는 작동하는 미디어 경로를 대체하지 못했다.
  • RTSP는 서버가 여전히 상태를 보유하고 수용 가능한 생존 증거를 받는 동안에만 상태를 유지했다. TEARDOWN, 시간 초과 또는 다른 종료 동작은 다음 명령이 454 Session Not Found로 응답하게 만들 수 있었다.

원격 제어기는 영구 전선을 필요로 하지 않았다

첫 RTSP 사양은 1998년, 그 목적 자체에 내재된 구조적 모순과 함께 등장했다. 시청자는 VCR 같은 제어 기능을 원했다. 스트림을 준비하고, 재생하고, 일시 정지하고, 탐색하고, 정지하는 것이다. 그런데 연속 미디어는 보통 이 명령을 실어 나르는 채널이 아닌 다른 곳으로 흘러갔다. 제어 프로토콜은 HTTP처럼 보였지만, 미디어 서버는 단발적인 요청보다 훨씬 많은 것을 기억해야 했다.

RFC 2326은 특유의 직접적인 문장으로 이 모순을 해결했다. RTSP 연결이라는 개념은 존재하지 않는다는 것이다. 서버는 식별자로 표시되는 세션을 유지하며, 그 세션은 TCP 같은 전송 계층 연결에 묶이지 않는다. 하나의 시청 컨텍스트가 유지되는 동안 클라이언트는 여러 신뢰성 연결을 열고 닫을 수 있었다.

그렇다고 TCP가 무관해지는 것은 아니었다. 명령은 여전히 서버로 가는 경로가 필요했고, 응답에는 반환 경로가 필요했으며, 인터리브된 미디어는 제어 스트림을 공유하기도 했다. 이 설계가 주장하는 바는 더 좁았다. 기억된 작업의 수명은 명령 하나가 도착한 소켓의 수명과 동일하지 않다는 것이다.

이것이 원격 제어기와 그 전선의 차이였다. 전선을 뽑으면 다음 버튼 누름이 막히지만, 그것만으로 기계가 선택된 영화, 협상된 전송 방식, 현재 상태 또는 묶인 스트림들을 잊게 되지는 않았다.

설명 문서는 세션을 가리킬 수 있었지만 세션을 만들지는 않았다

클라이언트가 서버 상태를 요청하기 전에 흔히 프레젠테이션 설명을 먼저 얻었다.RFC 4566은 SDP를 미디어 유형, 형식, 전송 주소 및 기타 세션 메타데이터의 표현으로 정의했다. 그것은 의도적으로 형식에 불과했고, 제어 프로토콜을 실어 보내거나 실행하지 않았다.

이 구분은 잊기 쉽다. 두 어휘 체계 모두세션이라는 단어를 쓰기 때문이다. SDP 문서는 오디오와 비디오를 서술하고, 제어 참조를 제공하며, 소프트웨어에 무엇이 이용 가능할지 알려줄 수 있다. 그러나 그것은 서버가 포트를 예약했거나, 전송을 수락했거나, 버퍼를 할당했거나, 특정 시청자의 RTSP 상태를 만들었다는 증명이 되지 못한다.

RTSP는 SETUP으로 그 경계를 넘었다. 클라이언트는 미디어 자원을 지정하고 자신이 전송을 수신할 수 있는 전송 매개변수를 제시했다. 성공한 서버는 수용 가능한 대안을 선택하고, 관련 매개변수를 저장하고, 그것들을 반환했다.RFC 7826, 즉 2016년 RTSP 2.0 교체 사양에서는 이것이 RTSP 세션 컨텍스트의 생성으로 서술된다.

응답에는 또한 서버가 만든 값이Session헤더에 실렸다. 설명은 "어떤 프레젠테이션과 제어 자원이 존재하는가?"에 답했다. SETUP은 "이 서버가 이 전송에 대해 어떤 상태를 수락했는가?"에 답했다. 두 사실은 서로 대체될 수 없었다.

두 번째 주소는 기억된 상태를 가리켰다

미디어 URI는 제어할 수 있는 무언가를 식별했다. 세션 식별자는 수락된 하나의 전송 컨텍스트를 다른 컨텍스트와 구분했다. 한 클라이언트가 동일한 URI에 대해 두 개의 세션을 만들거나, 오디오와 비디오 자원이 공통 제어 아래 묶일 때 그것이 중요했다.

RTSP 1.0은 식별자를 최소 8옥텟 길이의 불투명한 무작위 문자열로 만들었다. RTSP 2.0은 그것을 8~128자로 제한하고, 암호학적으로 무작위한 생성을 요구하며, 대략 128비트의 엔트로피를 권장했다. 그것이RFC 4086을 참조하는 지점은 추측 저항성을 다룬다. 약하거나 예측 가능한 절차에서 나온 식별자는 외부자가 발견하기 쉽다.

더 강한 무작위성이 그 문자열을 완전한 보안 체계로 바꾸지는 않았다. RFC 7826은 곧바로 경고한다. 클라이언트, 서버, 신뢰된 프록시가 식별자를 기밀로 유지하지 않는 한, 그것은 세션 하이재킹에 대한 방어를 제공하지 못한다. 엔트로피는 값을 예측하기 어렵게 만들 수 있다. 그러나 그것은 시청자가 그 영화에 대해 권한이 있는지, 계정이 여전히 활성인지, 명령이 현재 정책상 허용되는지를 결정할 수 없다.

RTSP는 그 별개의 문제를 위해 HTTP 인증 프레임워크를 사용했다.RFC 7616에서 규정된 Digest 같은 메커니즘은 자격 증명을 요구하고 자체 nonce와 재사용 방지 통제를 갖는다. Session 값과 인증 응답이 하나의 요청에 함께 나타날 수 있었던 이유는 서로 다른 질문에 답하기 때문이다. 어느 저장된 컨텍스트인가, 그리고 어떤 보호 공간 아래에서 어떤 요청자인가?

알려진 Session 값에도 올바른 대상이 필요했다

클라이언트가 식별자를 알게 된 뒤에는 그 컨텍스트와 관련된 명령이 Session 헤더를 실었다. 그 덕분에 PLAY, PAUSE, TEARDOWN은 나중에 열린 TCP 연결로 도착하더라도 기억된 상태에 도달할 수 있었다. 그러나 그 헤더가 요청 URI를 지우지는 않았다.

집계된 세션은 이 경계를 드러낸다. 여러 미디어 스트림이 하나의 타임라인을 공유하여 한 번의 PLAY로 오디오와 비디오가 함께 시작될 수 있다. 기존 컨텍스트를 참조하는 SETUP은 다른 자원을 추가하라고 요청할 수 있다. 그 경우에도 RFC 7826은 집계 연산에 집계 제어 URI를 요구한다. URI는 프록시가 명령을 라우팅하도록 돕고, 서버에 어떤 자원이 조작되는지 알려주며, 유용한 로그 범위를 유지한다.

식별자는 내부 기록을 찾는 데는 충분할 수 있다. 그러나 그 기록에 연관된 모든 URI에 모든 메서드를 적용할 권한은 아니다. RTSP는 세 개의 별개 오류를 정의했다. 세션이 없는 경우, 현재 상태에서 유효하지 않은 메서드, 그리고 잘못된 범위에서 시도된 집계 연산. 이는 편리한 조회 키가 자원 식별성, 상태 기계의 권한, 명령 유효성을 하나의 필드로 합치는 변명이 되지 않도록 했다.

또한 실패한 확장을 경계 지었다. SETUP이 기존 컨텍스트에 자원을 추가하려다 실패하면, RTSP 2.0은 이전 세션과 전송 상태가 실패한 요청이 도착하지 않은 것처럼 유지되도록 요구했다. 부분적인 시도가 이미 수락된 제어 표면을 조용히 다시 쓸 수는 없었다.

하나의 세션은 연결을 바꿀 수 있었고, 하나의 연결은 여러 세션을 실을 수 있었다

RTSP 2.0은 연결 규칙을 더 명시적으로 만들면서도 이 분리를 유지했다. 서버는 지속적인 TCP 연결과 일시적인 연결을 모두 지원해야 했다. 클라이언트는 SETUP과 PLAY를 보낸 뒤 연결을 닫고, 나중에 PAUSE를 원할 때 새 연결을 맺을 수 있었다. 일시적 연결을 지원하는 한 쌍은 예컨대 NAT 시간 초과로 인한 TCP 손실을 견딜 수 있었다.

역의 배치도 유효했다. 하나의 지속 연결이 여러 RTSP 세션의 명령을 실을 수 있었다. 따라서 소켓이 시청 컨텍스트를 식별하지 않았다. 어느 시점에서든 RTSP 2.0은 특정 세션에 대해 하나의 에이전트가 사용 중인 연결을 하나로 제한하여, 서버가 서버 주도 요청을 어디로 보낼지 알 수 있게 했다. 그 운영상 제한이 세션 수명을 그 연결에 다시 묶은 것은 아니었다. 그것은 제어 트래픽의 현재 채널을 선택했을 뿐이다.

미디어 경로는 또 하나의 다른 계층이었다. RTP는 SETUP에서 협상된 UDP 포트를 사용할 수도 있고, 미디어가 제어와 인터리브될 수도 있었다. NAT와 방화벽 통과에는 여전히 실제 도달 가능성 증거가 필요했다.RFC 7825가 ICE를 RTSP가 제어하는 데이터그램 미디어에 맞게 조정한 이유가 정확히 그것이다. 유효한 제어 컨텍스트가 사용할 수 없는 미디어 후보와 공존할 수 있기 때문이다. Session 헤더는 어떤 상태를 조작할지 말할 뿐, 패킷이 네트워크를 건널 수 있는지는 말하지 않았다.

이어지는 기억은 생명 신호로 얻어야 했다

서버가 버려진 상태를 영원히 붙잡을 수는 없었다. Session 응답은 명령 사이 또는 다른 수용 가능한 생존 신호 사이에 얼마나 기다릴지를 알릴 수 있었다. 다른 값이 없으면 기본값은 60초였다. RTSP 2.0은 타임아웃 매개변수를 응답 전용으로 만들고, 확립된 세션 동안 그 길이를 바꾸는 것을 금지했다.

그 컨텍스트를 참조하는 모든 RTSP 요청은 생존 증거가 될 수 있었다. 순수한 keep-alive로는 RTSP 2.0이 빈 SET_PARAMETER 요청을 선호했다. RTP 배치에서는 RTCP 트래픽을 사용할 수도 있었다.RFC 3550은 미디어 발신과 수신 증거를 위한 송신자 및 수신자 보고서를 정의했고, RFC 7826은 서버의 발신원과 관련 네트워크 튜플에 연관된 보고서를 클라이언트 측이 여전히 존재한다는 증거로 인정할 수 있도록 했다.

그 증거는 의도적으로 확률적이었다. RTCP 보고서는 유실될 수 있고 보고 일정에 따라 도착한다. 서버는 보고서를 사람이 시청했다는 증명, 프레임이 디코딩되었다는 증명, PLAY 명령이 수행되었다는 증명, 구독자가 여전히 권한을 갖는다는 증명으로 만들지 않으면서도, 거짓 타임아웃의 확률을 매우 작게 만들 수 있다. 생존 증거는 프로토콜 상태를 유지할 근거였다. 그것은 미디어 경험의 영수증이 아니었다.

번호는 남아 있을 수 있지만 상태는 사라질 수 있었다

정상 종료에는 TEARDOWN을 사용했다. 집계 범위에서는 묶인 전송을 멈추고 컨텍스트를 파괴할 수 있었다. 허용된 미디어 수준 TEARDOWN은 한 구성 요소를 제거할 수 있었고, 마지막 제거가 세션을 끝냈다. 서버는 컨텍스트에 타임아웃을 적용하거나, 종료 방향으로 재지정하거나, 회복 불가능한 실패 이후에 그것을 끝낼 수도 있었다.

그 경계 너머에서 옛 식별자를 반복해도 아무것도 부활하지 않았다. RTSP의 454 응답, 즉 Session Not Found는 없는, 유효하지 않은, 또는 시간 초과된 Session 식별자를 다루었다. 같은 바이트가 클라이언트 쪽에는 완벽하게 기억되어 있어도 살아 있는 서버 상태를 가리키지 않을 수 있었다.

이것이 이 메커니즘의 오래가는 교훈이다. 식별자는 세션을담고있지 않았다. 그것은 서버가 통제하는 철회 가능한 기록의 주소였다. 연결의 지속성, 토큰 소유, URI 범위, 인증, 미디어 도달 가능성, 생존 신호는 모두 증거에 기여했지만, 그 어느 하나도 다른 것을 대행할 수 없었다.