요약

  • DELE는 POP3 메시지를 제거하지 않았다. 현재 세션 번호 하나에 표식을 남기고, 그 번호를 이후 명령에 사용할 수 없게 만들며,RSET으로 이 의도를 취소할 수 있는 상태로 두었다.
  • TRANSACTION 상태에서 클라이언트가QUIT를 발행했을 때만 UPDATE로 진입했다. 비정상 연결 종료나 비활성 타임아웃은 UPDATE를 우회하므로, 표식된 메시지를 반드시 보존해야 했다.
  • 이 경계는 다운로드가 중단된 뒤의 손실을 줄여 주었지만 원자적 커밋은 아니었다. RFC 1939는 UPDATE 오류로 표식된 집합의 일부 또는 전부가 제거되지 않을 수 있음을 허용하면서, 표식되지 않은 항목의 제거는 금지했다.

아직 일어나지 않은 성공적인 삭제

POP3의 가장 작고 위험한 문장은 안심시키는 만큼 단순했다. 바로+OK message deleted다. 평범한 영어로 읽으면 최종 결과처럼 들린다. 그러나 프로토콜 상태 머신으로 읽으면, 그것은 서버가 삭제 표식을 접수했다는 표시일 뿐이었다.

이 구분은 POP3의 1988년 명세인RFC 1081에 이미 존재했다. 클라이언트가 인증하면 서버는 사용자의 메일드롭을 열고 세션은 TRANSACTION에 들어간다.DELE 4는 그 열린 뷰에서 네 번째 위치를 가리켰다. 한번 표식되면 그 번호는 이후의 POP3 명령에서 더 이상 사용할 수 없었다. 그러나 바이트와 저장 객체는 그대로 남았다.RSET은 대기 중인 모든 삭제를 표식 해제할 수 있었다.

실제 제거는 UPDATE를 기다렸다. 이 상태는 TRANSACTION에 있는 클라이언트가QUIT를 발행했을 때만 진입했다. AUTHORIZATION 상태에서 보내진 같은 네 글자 명령은 인증되지 않은 세션을 끝내기만 했다. 따라서 하나의 동사가 두 가지 결말을 가졌는데, 그 이유는 하나의 맥락에만 보호된 메시지 집합과 대기 중인 파괴적 의도가 존재했기 때문이다.

DELE뒤의 긍정 응답은 실제 근거였지만, 더 작은 사실의 근거였다. 서버가 이 열린 트랜잭션 안에 표식을 기록했다는 사실이다. 그것은 디스크 회수, 영속적인 톰스톤, 백업 변경, 심지어 이후의 UPDATE가 표식된 모든 메시지를 제거할 것이라는 보증조차 아니었다.

잠금이 목록을 일시적으로 일관되게 만들었다

TRANSACTION에 들어가기 전에, 서버는 필요한 경우 메일드롭에 배타 접근 잠금을 획득했다. 표준이 명시한 목적은 좁았다. UPDATE 이전에 메시지가 수정되거나 제거되는 것을 방지하는 것이다. 이렇게 서버는 열린 메시지에 1, 2, 3 순으로 번호를 매길 수 있었고, 클라이언트는 대화 도중에 번호 집합이 무너지지 않은 상태에서 그 위치들을LIST,RETR,DELE에 사용할 수 있었다.

잠금은 메시지 번호를 영구적인 식별자로 만들지 않았다. 이후 세션은 다른 집합을 열고 다른 위치를 부여할 수 있었다. 또한 메일드롭의 소유권을 클라이언트에 부여하지도 않았다. 메일 전달과 사이트 정책은 이 명령 시퀀스 바깥에 존재했다. 잠금은 파괴적 피연산자의 의미를, 서버가 클라이언트가 표식한 현재 열린 항목들이 무엇인지 알 수 있을 만큼 충분한 시간 동안 보호한 것이다.

이는 상태의 유용한 배분이었다. 클라이언트는 다운로드한 메시지를 안전하게 저장했는지 알 수 있었다. 서버는 메일드롭에 어떤 항목이 존재하고 제거될 수 있는지 알 수 있었다. POP3는 양측이 하나의 영속적인 트랜잭션 로그를 공유하도록 요구하지 않았다. 대신 취약한 구간을 잠금으로 한정하고, 파괴를 클라이언트가 의도적으로 닫을 때까지 연기했다.

1991년의RFC 1225와 1993년의RFC 1460은 이 설계를 그대로 유지했다. 중요한 역사는 연속성이다. 표식, 재설정 허용, UPDATE 시점의 제거, 잠금 해제, 보고, 종료.

끊긴 연결은 작별 인사의 대체물이 아니었다

이 아키텍처는RFC 1725에서 더 선명해졌다. 이 문서는 클라이언트가 발행한QUIT외의 어떤 이유로든 세션이 끝나면 UPDATE에 진입하지 않고 메시지를 제거해서는 안 된다고 명시했다. 비활성 타이머도 같은 규칙을 따랐다. 허용된 정책에서 최소 10분이 지난 뒤 자동 로그아웃은 응답 없이, 그리고 삭제 없이 연결을 닫았다.

이것은 예의상의 격식이 아니었다. POP3는 간헐적으로 연결되는 기계가 서버에서 메일을 가져오도록 설계되었다. 클라이언트가 아직 메시지를 로컬 저장소에 안전하게 반영하지 못한 상태에서 서버가 전송을 끝낼 수 있다. 파일시스템 쓰기 도중 전원이 끊길 수 있다. 마지막 네트워크 바이트가 지나간 뒤, 애플리케이션이 자기 작업을 마치기 전에 링크가 끊길 수 있다. TCP 소멸이 삭제 동의로 간주된다면, 전송 계층의 실패가 불완전한 로컬 사본을 영구적인 손실로 바꿀 수 있었다.

따라서 서버는 부재가 아니라 프로토콜 행위를 요구했다.QUIT는 트랜잭션이 파괴적 단계로 넘어갈 수 있다는 클라이언트의 선언이었다. EOF, 리셋, 타임아웃, 소멸한 프로세스는 의도적으로 더 약한 근거였다.

이 규칙은 오프닝 메시지가 돌아오는 이유도 설명한다. 서버의DELE뒤+OK는 철회되지 않았다. 표식은 TRANSACTION이 유지되는 동안 유효했다. 비정상 종료는 UPDATE로 이어지는 대기 경로를 버렸다. 재접속하면, 삭제 표식이 없는 새로운 메일드롭 뷰가 시작된다.

UPDATE는 경계였지 원자성 약속이 아니었다

QUIT를 커밋이라 부르고 싶은 유혹이 있다. 이 비유는 그 한계가 계속 보일 때만 유용하다. 1996년 STD 53으로 발표된RFC 1939는 이 한계를 명시했다.

UPDATE에서 서버는 삭제 표식된 메시지를 제거하고 결과를 보고한다. 자원 부족으로 그 메시지들이 일부만, 혹은 전혀 제거되지 않을 수 있다. 명세는-ERR some deleted messages not removed를 허용한다. 제거가 성공하든 실패하든, 서버는 배타 잠금을 해제하고 TCP 연결을 닫는다. 표식되지 않은 메시지를 절대 제거해서는 안 된다.

이것은 전원인 데이터베이스 커밋이 아니다. 한정된 파괴적 시도다. 표식된 집합이 무엇에 손댈 수 있는지 한정하고, 최종 응답이 보고된 성공과 알려진 문제를 구분하며, 다음 세션이 현재 상태를 제공한다. 세 개의 표식 배치는 두 개의 제거와 한 개의 생존자를 낳을 수 있다.

순서는 프로토콜이 문장으로 없앨 수 없는 또 다른 모호성을 만든다. 서버가 제거를 수행한 뒤, 클라이언트의 최종 응답 사본이 도착하기 전에 연결을 잃을 수 있다. 클라이언트 입장에서 침묵은 UPDATE가 진입하지 않았는지, 어떤 제거도 전에 실패했는지, 부분적으로 성공했는지, 완전히 성공했는지를 말해 주지 않는다.DELE 4를 무작정 재시도하는 것은 안전하지 않다. 새 세션의 4번 메시지는 다른 항목을 가리킬 수 있기 때문이다.

복구에는 대조가 필요하다. 지원되는 곳에서UIDL은 세션에 걸쳐 생존한 메일드롭 항목을 대조하는 데 도움될 수 있지만, 어떤 항목이 왜 사라졌는지는 증명하지 못한다. 다른 클라이언트나 사이트 보존 정책도 메일을 제거할 수 있다. 모호한 작별 뒤의 올바른 질문은 “QUIT가 아마 성공했는가?”가 아니라 “지금 어떤 기대 항목이 존재하고, 어떤 독립적인 로컬 사본이 영속적인가?”다.

정책은 관문을 옮기지 않고 표식 집합을 넓힐 수 있었다

RFC 2449는 이후 기능 발견과EXPIRE신호를 추가했다.EXPIRE 0은 메일을 서버에 남겨 두는 것이 허용되지 않는다는 뜻이다. 세션이 UPDATE에 들어가면, 서버는RETR로 다운로드된 각 메시지에 대해 암묵적인DELE를 가정할 수 있다.

이 정책은 과잉 해석하기 쉽다. 여전히 다운로드 자체는 즉각적인 삭제를 일으키지 않는다. 암묵적 표식은 UPDATE에서 효력을 가지므로, 비정상 종료에는 같은 보호가 적용된다.EXPIRE는 승인된 제거 집합이 구성되는 방식을 바꿀 뿐, 비가역적 권한을RETR이나 TCP 종료로 옮기지 않는다.

다른 보존 정책도 여전히 구분된다. 사이트는 공표된 규칙에 따라 오래된 메일을 제거할 수 있으며, 이는 이후의 부재가 한 클라이언트의QUIT에 대한 인과적 접수가 아님을 의미한다. 기능, 클라이언트 의도, 서버의 시도, 관찰된 이후 상태는 별개의 기록이다.

IANA 서비스 레지스트리는 여전히 포트 110에pop3를 기록하고 있다. 이는 표준화된 만남 이름을 보존한다. 그것은 현재 배포 규모를 측정하지 않으며, 어떤 서버든 이 실패 경계를 올바르게 구현한다는 증명도 아니다.

POP3의 삭제 설계는 교훈으로 남을 만큼 절제되어 있었다. 분산 트랜잭션을 약속하지 않았다. 어떤 근거가 비가역성을 승인할 수 있는지를 결정했다. 표식은 되돌릴 수 있었다. 비정상적인 침묵은 동의가 아니었다. 작별 인사가 파괴적 단계를 열었다. 그럼에도 결과는 부분적일 수 있었고, 관찰되거나 대조되어야 했다.

따라서 이 프로토콜의 가장 중요한 삭제 응답은 첫 번째+OK가 아니었다. 그것은 무엇이 요청되었는지, 서버가 무엇을 시도했는지, 클라이언트가 무엇을 알았는지, 다음 메일드롭에 무엇이 남아 있었는지 사이의 구분이었다.

출처