요약

  • RFC 3338은 소켓 API와 호스트의 듀얼 IPv4/IPv6 스택 사이에 변환기를 두었다. AAAA 전용 피어에 대해서는 로컬 IPv4 풀에서 A 레코드 답변을 합성하고, 그 값을 IP 헤더 변환 없이 실제 IPv6 주소로 매핑할 수 있었다.
  • 반환된 IPv4 값은 변환기 범위의 상태였다. 풀 고갈, 재사용, API 의미론상의 격차, 그리고 호스트 AAAA 지원과 특정 서버 포트 사이의 불일치는 이 착시를 깨뜨릴 수 있었다. 따라서 매핑 생성, 변환된 호출, 전송 결과, 애플리케이션 결과에는 별개의 영수증이 필요했다.

리졸버는 애플리케이션이 이해하는 형태를 반환했다

IPv4 전용 프로그램은gethostbyname방식의 결과와 IPv4 소켓 구조체를 기대했다. 소스 코드가 존재하지 않을 수 있었기 때문에 소스를 고치는 것은 불가능했을 수 있다. RFC 3338은 네이티브 IPv6 네트워킹은 이미 갖추었지만 구형 애플리케이션을 여전히 실행하던 듀얼 스택 호스트를 위한 임시 호환성 계층을 제안했다.

BIA 이름 리졸버는 애플리케이션의 호출을 가로채 A 레코드와 AAAA 레코드를 모두 조회했다. AAAA만 존재하면 주소 매퍼가 내부 IPv4 풀에서 값을 선택하고 이 쌍을 저장해 애플리케이션용 A 답변을 구성했다. 프로그램은 익숙한 4바이트 형태를 받고 아무 변경 없이 진행했다.

나중에 프로그램이 그 값을 IPv4 소켓 호출에 전달하면 함수 매퍼가 호출을 가로채 IPv6 주소를 조회하고 대응하는 IPv6 API를 호출했다. 패킷은 네이티브 IPv6 스택을 통해 이동했다. Bump-in-the-Stack과 달리 BIA는 네트워크 계층에서 IPv4와 IPv6 헤더를 다시 쓸 필요가 없었다.

겉보기 주소는 원격 인터페이스가 아니라 테이블 상태를 가리켰다

일반적인 네트워크 주소는 견고한 해석을 불러온다. 이 값이 네트워크상의 인터페이스나 엔드포인트를 식별한다는 해석이다. BIA의 합성 값은 더 좁은 의미를 가졌다. 특정 변환기 테이블 내에서, 특정 생성 시점에, 하나의 IPv6 주소를 참조했다.

RFC 3338은 내부 풀에 0.0.0.1부터 0.0.0.255까지 할당되지 않은 값을 제안했다. 이 값들은 호스트 밖으로 나가도록 의도된 것이 아니었다. 그 고유성은 변환기의 범위 안에서만 의미가 있었다. 노드별 테이블, 사용자별 테이블, 프로세스별 테이블은 같은 비트에 서로 다른 의미를 부여할 수 있었다.

따라서 합성 값만 로그에 남기면 모호했다. 유용한 기록에는 테이블 범위, 항목 생성 시점, 생성 트리거, IPv6 참조 대상, DNS 답변 세트, 프로세스 식별자가 필요하다. 이 주소는 전역적으로 의미 있는 목적지라기보다 파일 디스크립터에 가까웠다.

재사용은 어제의 핸들을 오늘의 다른 피어로 바꿀 수 있었다

풀은 유한했다. 수많은 IPv4 애플리케이션이 수많은 IPv6 호스트에 접속하면 주소가 고갈될 수 있었다. RFC는 가장 오래된 매핑을 해제하고 그 IPv4 값을 재사용하는 방식을 논의했다. 이는 용량을 회복했지만 핸들의 참조 대상을 바꾸었다.

애플리케이션, 캐시, 로그 또는 지연된 콜백이 보관한 오래된 사본은 이제 변환기를 통과해 다른 IPv6 호스트로 해석되면서도 여전히 유효해 보일 수 있었다. 이 위험은 중복된 전역 라우팅을 필요로 하지 않았다. 한 대의 기계 내부에서 수명에 대한 합의가 깨지는 데서 비롯되었다.

안전한 증거는 할당, 마지막 사용, 축출, 재사용, 생성 시점을 기록해야 한다. 조회 결과는 소켓 호출이 발생한 시점에 활성화된 생성 시점과 결합되어야 한다. 재사용 전과 후의 같은 4바이트는 운영상 동일한 식별자가 아니다.

API 변환이 두 API를 의미론적으로 동일하게 만들지는 않았다

함수 매퍼는 대응하는 IPv4와 IPv6 소켓 함수를 변환했지만 RFC 3338은 두 API가 완전히 호환되지 않는다고 경고했다. IPv6는 IPv4에 대응하는 기능 없이 새 기능을 도입했다. Raw 소켓, 보조 데이터, ICMP 값, 애플리케이션 프로토콜에 내장된 주소는 OS에 따라 다른 작업을 만들었다.

함수 치환이 성공했다는 것은 호출이 발생했다는 것을 증명할 뿐, 모든 옵션, 오류, 부작용이 의미를 유지했다는 것을 증명하지 않는다. 애플리케이션은 변환기가 정확히 재현할 수 없는 주소 패밀리, 구조체 크기, 와일드카드 규칙 또는 반환 오류에 의존할 수 있었다.

따라서 영수증 체계는 원래 API 이름과 인자, 변환된 API 이름과 인자, 옵션 변환, 운영체제 구현, 반환 상태, 애플리케이션 해석을 함께 보관해야 한다. "헤더 변환 없음"은 한 계층을 단순화했을 뿐, 의미론적 변환을 지우지는 않았다.

호스트의 AAAA 레코드가 선택된 서비스가 IPv6를 사용한다는 증거는 아니었다

듀얼 스택 서버 기계는 일부 서비스가 IPv6를 지원하는 반면 한 포트의 애플리케이션은 IPv4 전용으로 남아 있는 채 AAAA를 공개할 수 있었다. BIA를 사용하는 IPv4 클라이언트는 AAAA 경로를 선택해 호스트에는 도달하되 서비스 경계에서 실패할 수 있었다.

RFC 3338은 반환된 모든 주소를 시도하는 방식을 고려했다. TCP의 경우 BIA가 실패한connect를 관찰하고 반복할 수 있었다. UDP의 경우 성공이 즉각적이고 관찰 가능한 응답을 만들지 않을 수 있어 변환기가 어느 주소가 작동했는지 신뢰할 수 있게 알 방법이 없었다. 애플리케이션 스스로 반복을 수행해야 할 수도 있었다.

이 구분은 모든 전환 기술에서 살아남는다. DNS는 이름이 레코드를 갖고 있음을 증명한다. 네트워크 도달성은 패킷이 주소에 도달할 수 있음을 증명한다. 리스닝 서비스는 포트에 관한 무언가를 증명한다. 애플리케이션 성공은 요청된 작업을 증명한다. 어느 것도 다음 단계를 대체할 수 없다.

호환성 계층은 포팅을 미루는 핑계가 될 수 있었다

RFC는 강한 제품 경계를 그렸다. BIA는 실험적(Experimental) 기술로, IPv6 스택을 갖추고 소스를 이용할 수 없는 레거시 애플리케이션을 실행하는 얼리 어답터에게 유용했다. 주류 프로덕션 환경에서는 권장되지 않았다. 소스가 존재한다면 개발자는 BIA를 사용하는 대신 애플리케이션을 포팅해야 하며, 이 메커니즘이 그 작업을 연기하는 핑계가 되어서는 안 된다고 명시했다.

이 경고는 호환성 계층의 제도적 위험을 인식한 것이었다. 오늘의 격차를 해결하는 다리는 매핑, 예외 규칙, 운영 의존성을 쌓아 올려, 결국 제거하는 것이 원래의 포팅보다 더 어려워질 수 있다.

단기 소유자는 애플리케이션 사용이 지속되는 이점을 얻는 반면, 미래의 운영자는 숨겨진 리졸버 동작과 상태 기반 주소 의미를 물려받는다. 종료 기준은 배포 영수증에 포함되어야 한다. 어떤 애플리케이션이 대상인지, 포팅 주체가 누구인지, 어떤 호출이 계속 미지원인지, 어떤 관찰이 다리를 제거할 수 있음을 증명하는지.

이후의 연결 레이싱은 관련 문제를 다른 방식으로 해결했다

RFC 2767의 BIS는 스택의 더 아래에서 변환을 수행하고 RFC 2765의 SIIT에 의존했다. RFC 3338은 명시적으로 적응을 API 경계로 옮겼다. RFC 2893은 당시 듀얼 스택 전환 환경을 제공했다. RFC 3493은 이후 기본 IPv6 소켓 확장을 문서화했고, RFC 4038은 애플리케이션 전환 선택지를 조사했다.

RFC 6555와 그 업데이트인 RFC 8305는 이후 주소 패밀리 간에 연결 시도를 경쟁시키거나 순서화하는 Happy Eyeballs 방식을 규정했다. 이들은 지연과 폴백을 다루지만, 합성 IPv4 값을 IPv6 피어의 사설 별칭으로 만들지는 않는다. 이후 알고리즘을 BIA에 비추어 읽으면 중요한 역사적 차이가 사라진다.

RFC 4291은 IPv6 주소 지정을 정의하지만 BIA의 합성 IPv4 풀을 전역적으로 의미 있는 것으로 만들지는 않는다. 이 표준들 중 어느 것도 벤더나 운영자가 RFC 3338을 배포했다는 것을 보여주지 않는다.

모든 호환성 핸들에는 생성 번호가 필요하다

BIA의 우아한 발상은 그 아래의 구현을 바꾸면서 애플리케이션의 인터페이스를 보존한 것이었다. 대가는 숨겨진 상태였다. 주소처럼 보이던 것은 변경 가능한 로컬 테이블에 대한 참조가 되었고, 평범한 소켓 호출처럼 보이던 것은 가로채는 변환이 되었다.

지속적인 운영 교훈은 표현과 그것을 해석하는 권위를 함께 기록하는 것이다. 합성 A 응답은 매핑 영수증을 가져야 한다. 변환된 호출은 원래 의미와 결과 의미를 가져야 한다. 연결은 실제 IPv6 목적지와 서비스 결과를 가져야 한다.

이런 영수증이 없으면 조사자는 IPv4 형태의 숫자를 보고 그것이 결코 갖지 못한 전역적 의미를 부여한다. RFC 3338은 전환 메커니즘이었지만, 동시에 핸들에 관한 교훈이었다. 비트가 식별자가 아니며, 살아 있는 매핑이 식별자라는 교훈이었다.

출처