요약

  • TCP 긴급 메커니즘은 두 번째 전달 경로를 만들지 않았습니다. URG는 포인터에 의미를 부여하고, 수신자에게 일반 시퀀스 공간 안의 한 경계가 소비될 때까지 긴급 모드에 들어가라고 요청했습니다.
  • Telnet과 FTP는 이 알림을 이용해 막힌 작업 중에 주의를 끌었지만, 동기화 증거는 스트림 내부의 DATA MARK가 제공했습니다. 알림들은 서로 합쳐질 수 있었고 명령 수를 세지 않았습니다.
  • 표준은 잠시 포인터를 1바이트만큼 밀었지만 배포된 스택 대부분은 따르지 않았습니다. RFC 6093은 배포된 의미를 복원하면서 새 애플리케이션에 이 메커니즘을 피하라고 말했고, RFC 9293도 그 호환성 타협을 유지합니다.

스트림 안에 남은 인터럽트

이 이름은 잘못된 정신 모델을 불러일으킵니다. "긴급 데이터"는 큐를 뛰어넘는 특권 소포처럼 들립니다. 그러나 TCP는 그런 파이프를 제공하지 않았습니다.RFC 793은 일반 헤더에 16비트 필드를 넣고 URG가 설정되었을 때만 의미를 갖도록 했습니다. 이 필드를 세그먼트 시퀀스 번호에 더하면 수신자는 같은 바이트 스트림 안의 한 지점을 알게 됩니다.

그 지점이 이미 소비된 바이트보다 앞에 있는 동안, TCP는 애플리케이션에게 긴급 모드에 들어가라고 알립니다. 소비가 따라잡으면 일반 모드를 알립니다. 포인터가 갱신되어도 또 다른 가시 이벤트가 나타날 필요는 없으므로, 송신자 표시와 수신자 알림이 신뢰할 수 있는 1:1 대응을 이루는 일은 없었습니다.

Telnet에는 두 번째 파이프가 아니라 주의가 필요했다

애플리케이션 문제는 실재했습니다. 사용자가 중단을 원할 때 터미널 서버는 출력을 내는 중일 수 있었습니다.RFC 854는 TCP 긴급 알림을 Telnet DATA MARK와 짝지었습니다. 긴급 표시는 특별 처리를 깨웠고, 수신자는 일반 스트림을 훑어 사이의 문자를 버리고 마크를 찾은 뒤에야 일반 모드로 돌아왔습니다.

이 구분은 중요했습니다. 여러 Synch 신호가 합쳐질 수 있었습니다. TCP가 DATA MARK가 나타나기 전에 긴급 정보의 끝을 보고할 수 있었지만, Telnet은 계속 훑어야 했습니다. 스트림 내부의 명령이 전송 계층 표시가 줄 수 없는 애플리케이션 의미를 제공했습니다.

RFC 959는 FTP에서 이 패턴을 재사용했습니다. 서버가 제어 작업과 데이터 작업을 동시에 감시할 수 없다면, 클라이언트는 Telnet Interrupt Process와 Telnet Synch를 보낸 뒤 ABOR 또는 STAT를 보낼 수 있었습니다. 긴급 이벤트가 주의를 끌었고, 뒤따르는 FTP 명령이 여전히 무엇을 할지 결정했습니다.

하나의 사양 안에 두 개의 엔드포인트

RFC 793의 헤더 설명은 포인터가 긴급 데이터 다음 옥텟을 가리킨다고 했습니다. 그러나 상태 머신 텍스트는SND.UP를SND.NXT-1로 설정하는데, 이는 마지막 긴급 옥텟을 가리킵니다. 차이는 1바이트지만, 프로토콜 경계는 1바이트의 차이에 달려 있습니다.

RFC 1011은 1987년에 17페이지의 표현이 잘못되었다고 판정했습니다.RFC 1122는 1989년에 LAST+1이 아니라 LAST를 호스트 요구사항으로 만들었습니다. 또한 임의 길이의 긴급 시퀀스와 애플리케이션에 대한 비동기 알림을 요구했습니다.

이는 평범한 사양 수리처럼 보였습니다. 모호성을 식별하고, 경계를 선택하고, 구현체의 수렴을 요구하는 일이었습니다. 그러나 네트워크는 다른 판결을 내렸습니다.

소켓 API가 1바이트를 별개로 보이게 했다

RFC 6093은 테스트된 거의 모든 널리 쓰이는 구현체가 17페이지의 '다음 옥텟' 관례를 유지했다고 보고했습니다. 더 중요하게는, 기본 소켓 동작이 흔히 마지막 긴급 바이트를 일반 읽기에서 제거하고MSG_OOB를 통해 노출했습니다. 전송 경계가 "대역 외"처럼 보이는 1바이트가 된 것입니다.

이 적응은 임의 길이 메커니즘을 1바이트 슬롯으로 좁혔습니다. 이후의 긴급 표시는 애플리케이션이 아직 읽지 않은 바이트를 덮어쓸 수 있었습니다.SO_OOBINLINE은 인라인 전달을 복원할 수 있었지만, 소켓 옵션을 바꾸는 것으로 모든 피어나 중간 장비가 포인터를 같게 해석하게 되지는 않았습니다.

미들박스는 긴급성을 지울 수 있었다

보안 장비는 엔드포인트와 검사 로직이 서로 다른 바이트를 파싱할 수 있는 스트림에 직면했습니다. 일부는 URG를 지우고 포인터를 0으로 만들었습니다. 데이터는 인라인으로 계속 흘렀지만, 특별한 알림을 기다리던 애플리케이션은 그것을 받지 못할 수 있었습니다. 막힌 처리를 깨우도록 설계된 제어 경로가, 엔드포인트가 통제하지 않는 장비에서 스스로 사라질 수 있었습니다.

이는 모든 미들박스가 똑같이 동작한다는 증거가 아닙니다. 그러나 아키텍처적 약속을 무너뜨리기에는 충분했습니다. 애플리케이션은 널리 배포된 장비가 제거할 수 있고, 수신자 API가 서로 호환되지 않는 경계로 노출할 수 있는 신호에 정확성을 의존할 수 없습니다.

표준은 움직였지만 경고는 굳어졌다

RFC 6093은 쓰이지 않은 수정보다 상호운용성을 선택했습니다. 알려진 구현체들이 따르던 '다음 옥텟' 의미를 복원한 것입니다. 동시에 새 설계에서 메커니즘을 철회했습니다. 새 애플리케이션은 긴급 표시를 사용해서는 안 되고, 구현체는 레거시 사용자를 위해 유지해야 하며, 남은 애플리케이션은 인라인 전달을 요청하고 URG가 지워져도 정확하게 동작해야 합니다.

RFC 9293은 현재 TCP 사양에 같은 타협을 그대로 담고 있습니다. 지원은 필수입니다. 새 애플리케이션의 의존은 권장되지 않습니다. 호환성이 옛 대화를 보존하지만, 레거시 필드를 신뢰할 수 있는 새 추상화인 것처럼 가장하지는 않습니다.

출처와 근거의 한계

이 RFC들은 스트림 내부 경계의 의도, Telnet과 FTP의 사용, 1바이트 수정, 관찰된 구현 관행, 미들박스 간섭, 현대적 요구사항을 확립합니다. 그러나 특정 배포 날짜, 모든 곳에서 동일한 소켓 동작, 모든 경로에서의 신뢰할 수 있는 통과는 증명하지 않습니다. 긴급성은 TCP의 순서 제어, 혼잡 제어 또는 애플리케이션 파싱을 우회하지 않습니다.

따라서 이 역사는 필드가 폐지된 이야기가 아닙니다. 비트는 회선에 남아 있지만, 새 소프트웨어는 그것이 보이는 약속에 정확성을 걸지 말라고 들었고, 그래서 권위가 은퇴하는 더 미묘한 퇴임입니다.