TCP의 오류제어

dogyeong·2021년 6월 27일
1

TCP/IP

목록 보기
2/4

TCP는 신뢰성 제공을 위해 오류 제어를 한다. 오류 제어는 오류가 발생한 세그먼트를 발견하는 메커니즘, 오류가 발생한 세그먼트가 발견되면 오류를 정정하기 위한 메커니즘으로 나눌 수 있다. 이러한 오류 발견 및 정정은 검사합(체크섬), 확인응답, 시간초과 등을 통하여 수행된다.

검사합(체크섬)

TCP는 모든 세그먼트에 필수사항으로 16비트 검사합 필드를 기록해야 한다. 수신자는 검사합을 이용해 세그먼트가 손상되었는지 판단하고, 세그먼트가 손상되었다면 손상으로 판명된 세그먼트를 버린다.

검사합 계산을 위하여 의사헤더를 만들어서 추가한다. 왜 검사합을 계산할 때 의사헤더를 포함하는 것일까? TCP 헤더만으로는 IP 헤더의 오류를 검출할 수 없기 때문이다. 만약 IP주소가 잘못 되었거나 프로토콜이 잘못된 경우(예를 들어, 패킷이 TCP이 아니라 UDP로 전송되는 경우)에는 의사헤더의 값으로 오류를 검출할 수 있다.

TCP 헤더 구조

의사 헤더(가상 헤더) 구조

송신자의 검사합 계산

  1. 12바이트 의사헤더(Pseudo header)를 만들어 세그먼트에 추가한다.
  2. 검사합 필드를 0으로 채운다
  3. 전체 비트들을 16비트로 나눈다.
  4. 전체 바이트 수가 짝수가 아니라면, 전부 0인 1바이트 패딩을 추가한다.
  5. 16비트 섹션을 모두 더한다.
  6. 더한 값에 1의 보수를 취한다. 이 16비트 값을 검사합 필드에 삽입한다.
  7. 의사헤더와 추가된 패딩을 제거한다.
  8. 캡슐화를 위해 TCP 데이터그램을 IP소프트웨어에 전달한다.

수신자의 검사합 계산

  1. 의사헤더를 TCP 사용자 세그먼트에 더한다.
  2. 필요하면 패딩을 더한다.
  3. 전체 비트를 16비트 섹션으로 나눈다.
  4. 모든 16비트 섹션의 합을 구한다.
  5. 그 결과의 1의 보수를 구한다.
  6. 결과가 0이라면 의사헤더와 추가된 패딩을 없애고 사용자 데이터그램으로 받아들인다. 그렇지 않으면 사용자 데이터그램을 폐기한다.

확인응답

TCP에서는 세그먼트의 수신을 확인하기 위하여 확인응답을 사용한다. 세그먼트의 수신을 누적되게 확인응답할 수 있도록 설계되었기 때문에 누적 확인응답(ACK; Accumulative Acknowledgement)이라 한다.
확인응답을 하는 몇 가지 경우가 있다.

  • 수신 측에서 확인응답을 다음 전송할 데이터에 같이 붙여서 보내는 것을 피기백(piggyback)이라 한다. 이렇게 확인응답을 보내면 전송하는 세그먼트 수를 줄여 트래픽을 감소시킨다.
  • 수신 측에서 더 이상 보낼 데이터가 없다면 이전에 수신한 데이터에 대해 확인응답을 보낸다.
  • 수신 측에는 세그먼트를 세 개 이상 확인응답하지 않은 상태로 가지고 있지 않도록 한다. 이것은 망의 혼잡을 야기할 수 있는 세그먼트의 불필요한 재전송을 방지한다.
  • 기대한 것보다 더 큰 값을 가진 순서에 어긋난 순서 번호를 갖는 세그먼트가 도착하면 수신 측은 즉시 수신하기를 기대하는 번호를 담은 ACK 세그먼트를 전송한다. 이는 누락된 세그먼트의 빠른 재전송을 위한 것이다.
  • 누락된 세그먼트가 도착하면 수신 측은 수신하고자 하는 다음 순서 번호를 알리기 위해 ACK 세그먼트를 전송한다.
  • 중복 세그먼트가 도착하면 수신 측은 즉시 확인응답을 전송한다.

재전송

재전송 시간초과

세그먼트 발신자는 전송하는 각 세그먼트마다 재전송 시간초과(RTO; retransmission time-out) 타이머를 구동한다. 타이머가 만료되면 해당 세그먼트는 훼손되거나 손실된 것으로 간주하고 세그먼트를 재전송한다.
확인응답만을 포함하는 세그먼트에는 시간초과 타이머가 설정되지 않으며, 이러한 세그먼트는 재전송되지 않는다.
TCP에서 RTO값은 가변적이며 세그먼트의 왕복시간(RTT; round trip time)을 기반으로 업데이트된다.

손실 세그먼트 재전송

세그먼트는 전송 중 버려지거나, 오류 검출 등의 이유로 수신자에 의해서 버려질 수 있다. 이렇게 세그먼트가 손실되면 재전송하여야 한다.
수신자는 입력 버퍼에 손실된 세그먼트의 자리를 비워놓는다. 빈 공간이 다 채워지기 전까지는 버퍼의 내용을 어플리케이션 계층으로 전달하지 않는다.

세 번째 세그먼트에 대해서 확인응답을 전송하지 않기 때문에 송신 측에서 설정된 타이머는 만료가 될 것이다. 타이머가 만료되면 송신 TCP는 세 번째 세그먼트를 재전송할 것이다.

빠른 재전송

세 번째 세그먼트가 손실된 경우를 가정해보자. 수신측은 4,5,6번째 세그먼트를 각각 수신할 때마다 확인응답을 전송한다. 그러면 송신 측은 동일한 값을 갖는 세 개의 확인응답 즉, 3개의 중복응답을 수신한다. 중복응답을 3개 수신하면 비록 세 번째 세그먼트에 대한 타이머가 만료되지는 않았지만 빠른 재전송을 위한 규칙에 의거하여 송신 측은 모든 확인응답이 기대하는 세그먼트인 세 번째 세그먼트를 즉시 재전송한다.

지연 세그먼트

TCP는 비연결 지향 프로토콜인 IP 위에서 전송되기 때문에 TCP 세그먼트들은 서로 다른 지연을 가진 서로 다른 경로를 거쳐서 목적지에 도달한다. 따라서 TCP 세그먼트도 지연될 수 있다.
수신 측은 지연 세그먼트를 손실이나 훼손 세그먼트와 동일한 방법으로 처리한다. 또한 지연 세그먼트는 중복 세그먼트로서 재전송된 이후에 도착할 수도 있다.

중복 세그먼트

위의 지연 세그먼트의 경우 수신 측에 의해서 손실로 처리되는 경우에 늦게 도착한 세그먼트는 중복 세그먼트가 된다. 중복 세그먼트가 도착한 경우 중복 세그먼트는 수신자가 기대하는 순서 번호 값보다 적은 순서 번호 값을 가지기 때문에 수신자 TCP는 중복 세그먼트를 버린다.

ACK의 손실 자동 교정

확인응답이 손실되더라도 다음 확인응답에 의해서 자동으로 대치될 수 있다. ACK는 이전 확인응답을 포함하는 의미이기 때문에 이전의 세그먼트들이 모두 정상적으로 전송되었다는 의미가 된다.

확인응답의 손실로 인해 발생하는 교착상태(deadlock)

수신자가 rwnd값이 0으로 설정된 확인응답을 전송함으로써 송신자로 하여금 일시적으로 윈도우를 폐쇄한 경우 발생할 수 있다.
윈도우를 폐쇄한 이후 수신 측이 이러한 제한을 없애고자 하지만 전송할 데이터가 없는 경우, ACK 세그먼트를 전송한다. 하지만 이 ACK가 손실된 경우에는 서로 기다리는 교착상태가 된다. 이와 같은 교착상태를 막기 위해 영속 타이머(persistence timer)가 설계되었다.

profile
Engineer

0개의 댓글