요약

  • RFC 3402는 재귀적 발견 알고리즘을 정의했다. 각 비단말(nonterminal) 규칙이 다른 데이터베이스 조회의 키를 생성했지만, 모든 치환은 시작 시점에 제공된 정확한 애플리케이션 고유 문자열(Application Unique String)에 대해 계속 작동했다.
  • 이 불변 조건은 위임된 권한과 대상 식별을 분리했다. 체인은 해석 대상을 조용히 변경하는 변환을 누적하지 않고도 조회 위치를 바꿀 수 있었다.

재작성(rewrite) 시스템을 오해하는 가장 쉬운 방법은 문장이 왼쪽에서 오른쪽으로 편집되는 상상이다. 한 규칙이 문장을 변환하고, 두 번째 규칙이 새 텍스트를 받고, 세 번째 규칙이 두 번째 결과를 다룬다. 최종 출력은 유용할 수 있지만 그 경로는 전화 게임이 된다. 모든 중간 단계가 다음 단계가 물려받는 대상을 재정의할 수 있기 때문이다.

RFC 3402는 바로 그 모델을 금지했다. 2002년 10월 표준 트랙(Standards Track)으로 발행되어 Dynamic Delegation Discovery System의 제2부가 된 이 문서는 지연 바인딩(lazy binding) 알고리즘을 기술했다. 애플리케이션은 애플리케이션 고유 문자열(AUS)로 시작한 뒤, 필요할 때 규칙을 발견하고 위임된 데이터베이스들을 순회하다가, 단말 규칙이 애플리케이션이 기대하는 결과를 만들어내면 멈춘다.

역사적 중요성은 무엇이 움직이고 무엇이 움직이지 않는가에 있다. 비단말 치환 결과는 다음 순서화 규칙 집합을 가져오는 데 쓰이는 키가 되었다. 그 결과는 새로운 AUS가 되지 않았다. 다음 규칙이 검사될 때 그 치환 표현식은 다시 원본 문자열에 적용되었다. RFC 3402는 이 요구를 규범적 언어로 명시했고, 애플리케이션 사양에 부과되는 의무 속에서 반복했다.

첫 단계는 의도적으로 달랐다. 애플리케이션이 정의하고 규칙 데이터베이스에서 가져오지 않는 First Well Known Rule이 AUS를 첫 번째 유효한 데이터베이스 키로 변환했다. 이 규칙은 발견을 애플리케이션 계약에 고정시켰다. 편리한 문자열을 우연히 받아들이는 데이터베이스가 있다는 이유만으로 클라이언트가 임의의 데이터베이스에서 시작하는 것을 막았다.

조회는 순서화된 규칙 집합을 반환했다. 클라이언트는 원본 AUS에 대해 치환 표현식을 순서대로 시도해 비어 있지 않은 결과가 나올 때까지 진행했다. 규칙은 Services, Flags, Priority도 함께 실었다. 이들은 장식적 필드가 아니었다. 규칙이 수용 가능한 서비스를 제공하는지, 결과가 단말인지, 그리고 동등한 선택지 사이에서 어떻게 선호할지를 애플리케이션에 알려 주었다.

서비스 거부가 전체 과정의 실패를 의미하지는 않았다. 일치한 규칙이 클라이언트가 사용할 수 없거나 사용하지 않으려는 서비스를 기술하고 있다면, 클라이언트는 그 규칙 다음의 이미 가져온 목록 안에서 재개했다. 이 세부 사항은 순서와 증거를 보존했다. 클라이언트는 조용히 목록 맨 위에서 다시 시작해 거부된 대안이 고려된 적이 없는 것처럼 행동할 수 없고, 또 다른 전환을 선언하지 않고 무관한 데이터베이스로 뛰어갈 수도 없었다.

수용된 규칙이 비단말이었다면, 그 치환 출력의 역할은 하나뿐이었다. 다음 데이터베이스 키. 애플리케이션은 그 키를 데이터베이스의 문법에 대해 검증하고 또 다른 조회를 수행했다. 다음 단계에서 새로 얻은 규칙들은 여전히 원본 AUS에 일치했다. 키는 참조할 권한 기관을 선택했을 뿐, 대상의 식별을 얻지는 않았다.

RFC 3402는 금지된 대안을 취약하고 오류가 나기 쉽다고 규정하며, sendmail 방식의 재작성 체인을 경고 사례로 들었다. 누적 체인에서는 예상치 못한 중간 출력이 이후 모든 규칙이 다루는 재료를 바꾼다. 진단을 위해서는 각 홉에서 가변 상태를 재구성해야 한다. DDDS 불변 조건 하에서는 모든 규칙을 하나의 안정적 입력에 대해 검사할 수 있고, 모든 중간 출력은 라우팅 키 또는 단말 결과로만 판단할 수 있다.

다른 시스템으로의 위임에 대한 절대적 금지가 아니라 정의된 경계가 있었다. 애플리케이션의 Flags는 처리를 중단하고 제어를 다른 DDDS 애플리케이션이나 프로토콜 전용 규칙 시스템에 넘길 수 있었다. RFC 3404의 프로토콜 전용p플래그가 그 예였다. 그러나 그것은 명시적인 알고리즘 맥락의 전환이었다. 원본 애플리케이션의 규칙들은 대체된 대상을 몰래 다루면서 계속 진행되지 않았다.

단말 규칙이 순환을 닫았다. 단말 규칙의 출력은 애플리케이션의 기대 출력 계약을 충족해야 했고, 규칙의 Flags 및 Services와 함께 반환되었다. 따라서 단말 문자열은 자체적으로 인증되는 것이 아니었다. 그것은 선언된 애플리케이션과 데이터베이스 하에서 알고리즘이 종단점에 도달했음을 보여줄 뿐, 그 자체로 다운스트림 서비스가 가용한지, 데이터베이스 권한 기관이 정당한지, 소비자가 결과를 수용하는지를 증명하지 않았다.

Priority도 마찬가지로 좁은 의미만 가졌다. 동등한 규칙들 사이의 선호, 즉 더 빠르거나, 더 저렴하거나, 더 나은 대안을 표현했다. RFC 3402는 이것이 부하 분산 메커니즘이 아니라고 명시적으로 말했다. 트래픽 분배는 다른 곳, 예컨대 선택된 애플리케이션이 사용하는 SRV에 속했다. Priority를 트래픽 가중치로 읽으면 결정론적 선호 신호가 표준이 약속하지 않은 동작으로 변한다.

신선도는 최적화를 제약했다. 클라이언트는 반복 작업을 피하기 위해 이전 키나 규칙을 기억할 수 있지만, 데이터베이스의 만료 의미론을 존중해야 했다. 이전에 사용한 규칙이 만료되었다면 애플리케이션은 1단계로 돌아갔다. 오래된 접두사에 신선한 접미사를 덧붙인 채 같은 위임 경로를 실행했다고 주장할 수는 없었다.

이 책임 분할은 알고리즘 자체보다 넓었다. 애플리케이션 사양은 AUS, First Well Known Rule, 허용되는 데이터베이스, 문자 집합 처리, 단말 출력을 정의해야 했다. 데이터베이스 사양은 저장, 조회, 키 및 규칙 형식, 삽입 규칙, 충돌 회피를 정의해야 했다. RFC 3401은 시리즈의 한 부분만 읽으면 오해를 초래하기 쉽다고 경고했다. 준수는 조합 안에서만 존재하기 때문이다.

이 추상화는 스스로 결정할 수 없는 것도 인정했다. DDDS는 AUS와 규칙으로부터 위임 결과를 도출할 수 있었다. 그러나 시각대, 결제, 권리, 기타 거래적 사실처럼 외부 지식을 요하는 조건은 자체적으로 판단할 수 없었다. 그런 사실을 설명 없는 규칙 결과에 밀어 넣으면 관찰 가능한 체인이 실제보다 더 권위 있는 것처럼 보이게 된다.

보안도 같은 논리를 따랐다. RFC 3402는 동적 위임 지점을 공격 표면으로 지목할 수 있었지만, 특정 애플리케이션과 데이터베이스 없이 구체적 보호 조치를 열거할 수는 없었다. RFC 3403의 DNS NAPTR 레코드, RFC 3404의 URI 해석, 그리고 RFC 2916의 초기 ENUM 작업은 각기 다른 의미론을 제공했다. 이들은 알고리즘을 예시했을 뿐, 모든 DDDS 구현이 모든 애플리케이션을 이해한다는 결론을 허용하지 않았다.

IANA ENUM Service Registrations 레지스트리는 하나의 후기 DDDS 애플리케이션에서 조율된 식별자를 보여주는 당대의 증거다. 등록은 어떤 레이블이 할당되었음을 증명할 뿐, 어떤 리졸버가 그것을 실행했는지, 어떤 규칙이 신선한지, 어떤 권한 기관이 이를 게시할 자격이 있는지, 어떤 단말 서비스가 성공했는지를 증명하지 않는다. RFC Editor는 현재 RFC 3402에 대해 검증된 편집 오류 한 건, Errata ID 7049를 등재하며 RFC 3404의p플래그 논의 섹션 번호를 4.4에서 4.3으로 바로잡고 있다. 이 수정은 불변 조건을 바꾸지 않는다.

따라서 DDDS의 운영 영수증에는 최종 문자열만으로는 부족하다. 원본 AUS와 애플리케이션 및 버전, First Well Known Rule, 데이터베이스 유형, 모든 조회 키, 반환된 각 순서화 규칙 집합, 레코드 식별자와 신선도, 치환 일치와 출력, 서비스 거부와 재개 위치, Priority 결정, 단말 플래그, 기대 출력 검증, 최종 소비자 결과까지 보존해야 한다.

Lu Heng의 최소 초기 사양(Minimum Initial Specification) 원칙은 이 아키텍처의 절제를 설명한다. 이 RFC는 독립 구현들이 공유해야 하는 최소 경계를 표준화하고, 애플리케이션 의미와 데이터베이스 메커니즘은 각자의 사양에 맡겼다. 실행 코드 우선(Running-Code Primacy)은 증명 규율을 더한다. 캡처된 신선한 규칙을 통해 원본 AUS를 재실행하고, 각 키와 재개 지점을 검증하며, 어떤 구현도 중간 키를 대상으로 대체하지 않았음을 보이는 것이다.

RFC 3402는 단순히 정규 표현식의 순서를 조직하지 않았다. 위임 전반에 걸쳐 식별을 보존했다. 권한 기관들은 다음 질문을 어디에 물어야 하는지 결정할 수 있었지만, 각 기관은 동일한 시작 대상에 대해 책임져야 했다. 체인은 움직일 수 있었다. 그 대상은 그렇지 않았다.

출처