요약

  • RFC 1185의 계산에서는 1 Gbit/s일 때 TCP 순서 번호 공간의 위험한 절반을 약 17초 만에 지나간다. 늦게 온 중복 패킷이 다시 그럴듯한 번호를 달 수 있다.
  • RFC 1323의 PAWS는 도착한 시간 표시와 TS.Recent를 비교해 열린 연결 안의 오래된 중복을 막았다. 연결이 24일 넘게 유휴 상태였다면 저장한 기준을 무효로 만들어야 새 패킷을 받을 수 있었다.

TCP는 바이트에 번호를 매기고, 번호를 다 쓰면 처음으로 돌아간다. 느린 통신에서는 옛 패킷이 네트워크에서 사라진 뒤에야 같은 번호가 다시 등장한다. 속도가 크게 오르면 번호가 늦은 패킷을 앞질러 한 바퀴 돌 수 있다. 문지기는 출입증 번호를 알아보고 어제 온 손님을 오늘 손님으로 들여보낸다.

1990년 10월의 RFC 1185는 이 위험을 숫자로 제시했다. 1 Gbit/s에서 중요한 순서 번호 공간의 절반을 지나는 데 약 17초가 걸린다는 표가 있다. 비교 대상으로 쓰인 TCP 세그먼트의 최대 생존 시간은 2분이었다. 번호의 재등장은 빨라졌지만 오래된 세그먼트는 아직 길 위에 있을 수 있었다. 이는 고속 경로를 놓고 한 설계 계산으로, 번호 말고 또 다른 표식이 필요하다는 결론으로 이어졌다.

1992년 5월의 RFC 1323은 TCP Timestamp 옵션을 도입했다. 왕복 시간을 재는 일과, 순서 번호의 순환에 대비하는 PAWS라는 일을 함께 맡았다. 수립된 연결에서 수신자는 최근 시간 표시를 TS.Recent로 보관했다. 새로 도착한 세그먼트의 TSval이 유효한 기준보다 작으면 확인 응답을 보내고 세그먼트를 버렸다. 시간 검사에 통과해도 일반적인 TCP 수신 창 검사는 계속됐다. 오래된 손님이 번호를 맞혀도 시계가 정체를 밝히는 셈이다.

양쪽 기기가 벽시계를 맞출 필요는 없었다. 송신자가 자신의 시간 값을 단조롭게 올리고, 수신자가 32비트 순환 산술로 비교하면 됐다. TS.Recent는 왕복 시간 측정에도 쓰여 하나의 연결 상태가 두 역할을 했다. PAWS는 같은 열린 연결로 들어오는 데이터와 확인 응답을 검사하며, 그 연결 안에서 생긴 오래된 중복을 가렸다.

그런데 문지기의 수첩도 늙었다. RFC 1323은 시간 표시 시계가 1초마다 한 번부터 1밀리초마다 한 번까지 움직이도록 허용했다. 가장 빠른 쪽에서는 32비트 값의 부호 기준 반 바퀴가 약 24.8일 만에 돌아온다. 연결을 열어 둔 채 그만큼 오래 아무것도 보내지 않았다고 하자. 송신자의 시계는 계속 간다. 다시 보낸 진짜 새 세그먼트가 수신자의 오래된 TS.Recent보다 작은 값으로 보일 수 있다. 낡은 수첩을 끝까지 믿는 필터는 새로 오는 세그먼트를 모조리 버리고 연결을 얼려 버린다.

RFC 1323은 수첩을 버리는 규칙을 정했다. 연결이 24일 넘게 유휴 상태라면 PAWS 구현은 TS.Recent를 무효로 만들어야 한다. 도착한 값이 작아 보일 때 수신자는 먼저 자신의 기준이 여전히 유효한지 확인한다. 기한이 지났으면 세그먼트는 PAWS 검사를 통과하고 새로운 기준을 제공할 수 있다. 일반 순서 번호 창 검사는 여전히 남는다. 오래된 출입 명부를 폐기한다고 경비실을 비우는 것은 아니다.

저자들은 가끔 유지 메시지를 보내 기억을 새롭게 하는 방안도 살폈다. TCP 규격이 그런 메시지를 요구하지 않았기에 무효화 방식을 택했다. 수신자는 상대방 시계의 속도도 모르므로 가장 빠른 경우를 기준으로 삼았다. 24일은 연결의 수명이 아니라 침묵한 시간이다. 계속 움직이는 연결은 기록을 갱신하고, 잠든 연결은 깨어날 길을 남겨 둔다.

후속 규격인 RFC 7323도 오래된 시간 표시의 문제와 24일 규칙을 유지했다. 1990년부터 1992년까지 TCP는 서로 다른 두 가지 낡음을 만났다. 고속 회선에서는 번호가 너무 빨리 되돌아왔고, 오래 쉬는 동안에는 그 번호를 검사할 시간 기록이 먼저 늙었다. PAWS는 문지기에게 옛 패킷을 알아보는 법과 자기 수첩을 버릴 때를 함께 가르쳤다.