요약

  • RFC 875는 공유 IP 데이터그램을 전달하는 인터넷 게이트웨이와, 서로 다른 주소·확인 응답·흐름 제어·애플리케이션 의미 체계를 조정해야 하는 번역 게이트웨이를 구분했다.
  • 중개자가 양쪽 프로토콜 세계를 모두 종단하는 순간, 그것은 연결 상태의 특이점이 되었다. 이중화, 장애 복구, 어느 한쪽의 모든 변경 사항은 또 하나의 명시적 설계를 요구했다.

한 페이지에 두 개의 네트워크를 그리자. 그 사이에 사각형 하나를 놓자. 들어가는 화살표 하나, 나가는 화살표 하나를 추가하고 그 사각형을 게이트웨이라고 부르자. 이제 이 다이어그램은, 아무도 통과 과정에서 무엇이 살아남아야 하는지 말하기 전에 통신이 가능하다고 주장하는 셈이다.

M. A. Padlipsky는 1982년 9월에 발표된 RFC 875,Gateways, Architectures, and Heffalumps에서 그 사각형을 공격했다. 이 메모는 표준이 아니었고, 배치된 번역기에 대한 조사 결과를 담지도 않았다. 이것은 아키텍처상의 지름길, 즉 호환되지 않는 프로토콜 스위트 사이의 게이트웨이를 마치 좀 더 야심찬 버전의 인터넷 게이트웨이인 것처럼 다루는 관행에 대한 경고였다.

이 구분이 중요했던 이유는, 인터넷의 평범한 게이트웨이가 의도적으로 작은 역할만 맡고 있었기 때문이다. 서로 다른 패킷 네트워크는 각기 다른 로컬 프레이밍, 주소 지정, 접속 절차를 사용할 수 있었지만, 그 위에는 동일한 인터넷 프로토콜을 실었다. 게이트웨이는 각 로컬 네트워크에 맞추어 적응하고 공유 객체를 전달했다. 번역·매핑 게이트웨이, 곧 Padlipsky의 T/MG에는 그런 안정적인 객체가 없었다. 이것은 한쪽의 어떤 주장이 다른 쪽의 어떤 주장에 대응하는지를 결정해야 했다.

얇은 공통 계층에는 이미 하나의 타협이 담겨 있었다

RFC 791은 상호 연결된 패킷 교환 네트워크를 위한 IP를 정의했다. 고정 길이의 인터넷 주소를 제공했고, 데이터그램이 서로 다른 패킷 크기를 가진 네트워크를 통과할 수 있도록 단편화를 제공했다. 그러나 종단 간 신뢰성, 순서 보장, 흐름 제어는 명시적으로 제공하지 않았다. 그 기능들은 다른 곳에 속했다.

그 부정적 공간은 아키텍처의 일부였다. IP 게이트웨이는 인터넷 주소를 검사하고, 다음 홉을 선택하고, 한 로컬 네트워크에서 데이터그램을 벗겨 다른 네트워크로 감쌀 수 있었다. TCP 종단을 가장할 필요가 없었다. RFC 791은 상위 계층 프로토콜은 게이트웨이에서 구현할 필요가 없다고까지 말했다.

RFC 793은 연결 상태, 신뢰성 있는 전달, 순서 보장, 윈도우, 긴급 표시를 호스트의 TCP에 두었다. 네트워크 계층과 전송 계층은 동일한 약속을 하지 않았다. 상호 운용이 가능했던 이유는 모든 참여자가 어느 계층이 어느 약속을 소유하는지 알고 있었기 때문이다.

RFC 875의 불만은 이종성이 불가능하다는 것이 아니었다. IP는 애초에 이종 패킷 네트워크를 통과하도록 설계되었다. 불만은 공통 허리 아래의 이종성과 그 위의 의미적 비호환성이 다르다는 점이었다. 게이트웨이는 로컬 프레임을 교체할 수 있다. 양쪽 모두 안에 담긴 IP 데이터그램이 여전히 같은 객체임에 동의하기 때문이다. 그러나 필드 이름을 바꾼다고 해서 빠진 애플리케이션이나 전송 계층의 보장을 대체할 수는 없다.

외부 차원이 없는 주소는 하나를 갖추도록 다시 포맷될 수 없었다

Padlipsky는 NCP와 TCP/IP로 시작했다. 과증한 예시 없이도 난점이 드러날 만큼 두 체계가 가까웠기 때문이다. NCP 호스트 인터페이스는 자신의 ARPANET 주소 공간 안에서 호스트를 식별했다. IP 주소는 네트워크 부분과 호스트 부분을 결합했다. 따라서 NCP 쪽에는 “목적지는 저 다른 네트워크의 이 호스트다”라고 명시할 평범한 자리가 없었다.

번역기는 여분 비트를 찾아보거나, 초기 연결 프로토콜을 바꾸거나, 인터넷 주소를 애플리케이션 데이터에 넣을 수 있었다. 어떤 해답을 고르든 본래 변경되지 않아야 할 NCP 환경을 바꾸게 된다. 문제는 숫자의 인쇄된 모양이 아니었다. 한쪽의 계약이 다른 쪽이 표현하는 범위를 갖고 있지 않았던 것이다.

RFC 875는 더 정직한 탈출로를 묘사했다. 중개자가 호스트가 되어 첫 연결을 종단하고, 사용자에게 원하는 외부 시스템을 물은 뒤 두 번째 연결을 시작하는 방식이다. Padlipsky는 두 개의 얼굴을 가진 신을 따라 이것을 “Janus Host”라고 불렀다. 특히 대화형 Telnet에는 유용할 수 있었지만, 더 이상 투명한 연결은 아니었다.

RFC 801, 즉 NCP/TCP 전환 계획은 이 경계를 실제로 작동하게 만들었다. Telnet 사용자는 릴레이 호스트에 접속해 특수 계정으로 로그인한 뒤, 반대쪽 환경에서 또 다른 Telnet 연결을 시작했다. FTP는 릴레이를 통해 파일을 두 번 옮겨야 했다. 메일에는 자체 릴레이 방식이 있었다. 릴레이는 하나의 프로토콜 스위트가 손실 없이 다른 스위트로 번역되었음을 증명하지 못했다. 애플리케이션별 인계가 노출되었을 뿐이다.

확인 응답이 잘못된 계층에서 도착할 수 있었다

주소 문제는 첫 번째 빠진 의미일 뿐이었다. NCP에서 Ready for Next Message 신호는 목적지 IMP로부터, 번역기가 개입할 때는 번역기 옆의 IMP로부터 왔다. 그 신호가 반드시 최종 외부 호스트의 상태를 기술하는 것은 아니었다.

T/MG는 신호를 지연시키고 데이터를 버퍼에 담아둘 수 있었다. 그러나 반대편 프로토콜 쪽의 어떤 사건이 이를 해제해야 하는가? 외부 네트워크가 로컬 전송을 확인 응답했다면, 그것이 종단 수신, 애플리케이션 소비, 아니면 단지 또 하나의 중간 큐에 대한 증거였는가? 변환기는 타이밍 관계를 만들어낼 수 있었다. 그러나 상대 프로토콜이 노출하지 않은 종단 간 사실을 만들어낼 수는 없었다.

그래서 흐름 제어의 불일치는 단순한 성능 문제를 넘었다. 백프레셔는 누가 늦춰야 하는지, 그리고 재개를 허락하는 증거가 무엇인지를 명명한다. 두 스위트가 서로 다른 경계에서 송신자를 멈춘다면, 게이트웨이가 그 불일치를 소유한다. 버퍼는 결정을 미루기만 할 뿐이며, 경로상에서 중개자를 가장 큰 상태 보유자로 만들 수 있다.

긴급 비트는 보편적인 비상 언어가 아니었다

RFC 875는 이어서 예외 신호를 다뤘다. NCP는 제어 링크 위의 인터럽트 명령을 갖고 있었다. TCP는 연결 내부의 Urgent 메커니즘을 갖고 있었고, Telnet은 Interrupt Process 명령을 실을 수 있었다. 다른 프로토콜 계열들도 신속 데이터를 제공했다. 모두 “이것을 빨리 처리하라”는 의미처럼 보였다. 그러나 반드시 같은 구성 요소에 명령하지는 않았다.

TCP 명세는 이 경계를 찾는 데 도움이 된다. RFC 793은 긴급 메커니즘이 수신 사용자가 긴급 정보를 처리하도록 자극하고 긴급 모드로의 진입과 이탈을 유지해야 한다고 말했다. 프로토콜 해석기에 우선 서비스만 제공하는 메커니즘은, 목적지 프로세스가 자신의 작업을 중단하라는 지시와 동등하지 않다.

따라서 한쪽에 필요한 동작이 없을 때 번역기는 답이 없는 매핑에 직면했다. 신호를 버리면 기능이 사라졌다. 신속 전달을 프로세스 인터럽트로 취급하면 권한을 발명하는 것이었다. 애플리케이션을 종단하고 로컬 정책을 구현하는 것은, 원래 프로토콜이 아니라 중개자가 선택을 하고 있음을 인정하는 것이었다.

Padlipsky는 University College London의 구체적인 사례를 보고했다. ARPANET Telnet과 X.25/X.28/X.29 계열 사이의 터미널 게이트웨이는 데이터를 옮길 수 있었지만, 메모에 따르면 에코 옵션만 통과했다. 이 관찰은 시스템에 대한 완전한 감사로 확대되어서는 안 된다. 그 가치는 더 좁다. 문자 전송이 성공했다고 해서 문자를 둘러싼 옵션 어휘까지 보존되었다는 증명이 되지는 않는다.

이중화는 사각형 안에 숨어 있던 상태를 드러냈다

번역기가 모든 대응 관계를 관리해냈다고 가정하자. 이제 그것은 두 개의 연결 식별자, 두 개의 시퀀스 공간, 두 개의 흐름 제어 상태, 주소 바인딩, 옵션 상태, 애플리케이션 가정을 보유하게 된다. 그 옆에 설치된 두 번째 번역기는 이 사실들을 자동으로 가지지 못한다.

RFC 875는 결과물인 중개자를 특이점(singularity point)이라고 불렀다. 한 T/MG를 통해 만들어진 연결은 그 박스에 귀속되었다. 패킷 계층의 대체 경로는 고장난 링크를 우회할 수 있었지만, 번역기의 사적인 대화를 재구성할 수는 없었다. 이중화는 상태 전이, 충돌 처리, 접수(테이크오버)를 위한 또 하나의 프로토콜을 요구했다. 다이어그램 속 그 박스는 분산 시스템이 되어 있었다.

같은 의존성이 시간의 흐름에도 나타났다. 번역기는 쌍별로 존재했다. 스위트 A에서 스위트 B로. 스위트 C를 추가하려면 더 많은 쌍이 필요했다. 어느 한쪽 스위트를 바꾸면 영향을 받는 모든 번역기를 검토하고 다시 만들어야 했다. 편리한 경계였을 그것이 양쪽의 릴리스 일정과 모호성을 축적해갔다.

이후의 라우터 명세는 이 구분을 더 선명하게 만들었다

RFC 1009는 이후 인터넷 게이트웨이를 IP 수준의 라우터로 정의했다. 여전히 상당한 적응 작업이 필요했다. 연결된 각 네트워크에 대해 프레이밍, MTU, 로컬 네트워크 주소 매핑, 로컬 흐름 제어나 오류 표시를 처리했다. 다음 홉을 선택하고 버퍼를 관리하고 라우팅에 참여했다.

그러나 이 적응들 사이에서 전달되는 객체는 여전히 IP 데이터그램이었다. 게이트웨이는 모든 애플리케이션의 주소 어휘를 번역하거나, 외부 종단의 확인 응답을 재현하거나, 하나의 프로세스 제어 의미를 다른 의미로 바꾸겠다고 약속하지 않았다. 얇다는 것은 사소하다는 뜻이 아니었다. 공통 계약에 경계가 있다는 뜻이었다.

이후의 미들박스들은 정확한 역사가 아니라 같은 질문을 반복했다

비슷한 문제의 재발을, RFC 875가 모든 미래의 중개자를 예언했다는 주장으로 읽어서는 안 된다. 이후 문서들은 서로 다른 시스템을 다룬다.

RFC 2775는 주소 번역이 종단 간 주소 투명성을 깨뜨리며, 페이로드에 주소를 실어 나르는 애플리케이션은 애플리케이션 게이트웨이나 프록시를 필요로 한다고 지적했다. 새로운 주소 의존 애플리케이션마다 새로운 중개자 지식이 요구될 수 있다.

RFC 3234는 미들박스를 분류하면서 그 유용한 목적들을 진지하게 다루었다. 동시에 새로운 실패 양상들도 기록했다. 재라우팅은 기존 상태가 없는 박스를 만날 수 있고, 중간 박스의 충돌은 세션에 영향을 주며, 진단은 여러 계층에 걸친다. 애플리케이션 게이트웨이가 상태를 유지하는 이유는 불투명한 데이터그램을 전달하는 것이 아니라 애플리케이션 의미 체계에 참여하기 때문이다.

RFC 4966은 이후 특정 기술적·운영적 이유로 NAT-PT를 Historic 상태로 옮겼다. 그것은 내장 주소 결합, 호환되지 않는 IPv4/IPv6 의미 체계, 단편 상태 문제, 매핑 수명, DNS-ALG 확장성, 그리고 단일 실패·공격 요지를 문서화했다. 이 발견들은 모든 번역 메커니즘을 비난하지 않는다. “패킷을 번역하라”는 결코 완전한 명세가 될 수 없는 이유를 보여줄 뿐이다.

빠진 의미는 눈에 보이는 결정이 되어야 했다

RFC 875의 지속적인 공헌은 다이어그램을 위한 하나의 시험이다. 중개자를 통과하는 각 화살표에 대해, 어떤 주장이 들어왔고 어떤 주장이 나갔으며, 어느 주체가 대응 관계를 만들었고, 실패 시 어떤 증거가 남는지를 물어라.

양쪽 네트워크가 최소한의 프로토콜을 공유한다면, 게이트웨이는 좁게 유지될 수 있다. 공통 객체를 보존하면서 로컬 실행에 맞추어 적응한다. 스위트들이 서로 어긋난다면 선택지는 명시적인 것들뿐이다. 서비스를 교집합으로 축소하거나, 종단했다가 다시 시작하거나, 종단에 새로운 의미 체계를 추가하거나, 일부 기능은 통과하지 않음을 받아들이는 것.

어느 것도 마법 같은 번역이 아니다. 각각은 권한과 손실을 배정한다.

바이트는 도착할 수 있다. 주소는 다시 쓰였을 수 있다. 터미널은 에코할 수 있다. 그것들은 관찰 가능한 성과다. 그러나 확인 응답, 긴급성, 애플리케이션 옵션, 종단 간 연속성이 같은 의미를 유지했다는 증명은 되지 않는다. 게이트웨이는 양쪽이 명시한 것을 실어 나를 수 있다. 한쪽이 결코 하지 않은 약속을 발명할 수는 없다.

출처