[Computer network] Chapter 6 - Transport layer : TCP

이한량·2024년 11월 29일

Computer Network

목록 보기
9/11

1. TCP

  • TCP : 연결 지향형 프로토콜로, 신뢰성 있는 데이터 전송을 보장한다. TCP는 데이터 전송의 신뢰성을 보장하기 위해 다음 세 단계를 거쳐 통신을 진행한다.

    • Connection establishment (연결 설정)

    • Data transfer (데이터 전송)

    • Connection teardown (연결 종료)

  • Stream Delivery : TCP의 데이터 전송은 Stream of bytes 형태를 띄고 있다.

    • 각 패킷마다 순서가 존재하여 논리적 연결이 존재한다. 즉, 하나의 데이터 스트림을 이룬다.

    • 데이터를 여러 패킷(프래그먼트)으로 나누어 전송한 뒤 수신측에서 이를 재조립한다.

  • TCP Segment : 네트워크 환경마다 전송할 수 있는 데이터의 크기가 다르므로, 데이터를 여러 조각의 Segment로 나눠 전송하는 방식은 매우 중요하다.

  • Segment Format

    • TCP Control Field

1-1. Window in TCP

  • Window in TCP : TCP 환경의 Window는 Flow Control, Congestion Control, Error Control을 구현하는 핵심적인 역할을 한다.

    • Send Window

      • SfS_f : 전송했지만 ACK 메시지를 받지 못한 첫 번째 패킷(바이트)이다. ACK를 수신하면 이 경계는 오른쪽으로 이동(Sliding)하며, 해당 데이터는 버퍼에서 제거된다.

      • SnS_n : 다음으로 전송할 바이트(메시지)이며, 수신자가 허용한 윈도우만큼 전송이 가능하다.

      • 파란색 영역은 ACK 메시지를 받지 못한 패킷들의 영역, 흰색 영역은 전송 가능한 패킷들의 영역이다.

      • Shrinking : 네트워크 혼잡이나 수신자의 처리 용량 부족 등으로 인해 윈도우의 크기가 작아질 수 있다.

      • ACK 메시지를 받으면 이미 전송한 데이터에 대해서는 버퍼가 Closing, 전송할 데이터에 대해서는 버퍼가 Opening 된다.

    • Receive Window

      • 파란색 영역은 ACK 메시지를 전송하였지만, 아직 프로세스에 의해 처리되지 않은 패킷들의 영역, 흰색 영역은 패킷을 수용할 수 있는 버퍼 영역이다.

      • 송신자가 전송할 수 있는 패킷의 양은 수신자의 버퍼 크기(Window size)에 따라 결정된다.

      • RnR_n : 다음 패킷을 수신할 것으로 예상되는 버퍼 공간이다.

      • 이미 ACK를 보낸 패킷들은 프로세스에 의해 처리되면 Closing되며, Closing되는 만큼 버퍼가 Opening된다.

2. TCP Connection

  • TCP Connection : TCP환경에서 메시지(모든 세그먼트)는 송신자와 수신자 사이에 연결 설정된 논리적 경로를 통해 전송된다.

    • Connection Establish (연결 설정) : TCP는 연결 지향형 프로토콜이기 때문에, 통신이 이루어지기 전에 반드시 연결이 설정되어야 한다.
  • 2-way handshake scenario : TCP에서 2-way handshake로 연결 설정이 이루어지는 과정을 살펴 보자.

    • 첫 번째 시나리오 : 문제 없음

    • 두 번째 시나리오 : 연결 설정을 요청하는 메시지에 대해 응답 메시지(ACK)가 너무 늦게 도착해서 연결 설정이 실패

    • 세 번째 시나리오 : 이전에 보낸 메시지가 다음 연결에 영향을 미치는 경우

  • 3-way handshake : TCP는 2-way handshake에서 발생할 수 있는 문제를 방지하기 위해 3-way handshake 방식을 사용하여 연결을 설정한다.

    1) SYN (클라이언트 \rarr 서버)

    • 클라이언트는 연결을 요청하기 위해 SYN 세그먼트를 서버로 전송한다.

      • seq = 8000 : 세그먼트 시퀀스 번호

      • SYN : SYN flag

    2) SYN + ACK (서버 \rarr 클라이언트)

    • 서버는 항상 열려있는(Passive open) 상태에서 클라이언트의 요청을 대기한다.

    • SYN 요청을 받은 서버는 연결 요청에 대한 응답 메시지 SYN + ACK가 설정된 세그먼트를 클라이언트로 전송한다.

      • seq = 15000 : 세그먼트의 시퀀스 번호

      • ack = 8001 : 클라이언트의 시퀀스 번호에 대한 응답 번호

      • rwnd(receive window) = 5000 : 서버에서 수용 가능한 용량(바이트)

      • SYN + ACK : SYN + ACK flag

    3) ACK (클라이언트 \rarr 서버)

    • 클라이언트는 서버의 응답에 대해 ACK 플래그가 설정된 세그먼트를 전송한다.

      • seq = 8001 : 세그먼트 시퀀스 번호

      • ack = 15001 : 상대의 시퀀스 번호에 대한 응답 번호

      • rwnd = 10000 : 클라이언트에서 받을 수 있는 바이트

    4) Data Transfer : 연결이 설정되었고, 데이터 전송이 시작된다.

    5) Terminate : 데이터 전송이 끝나면, 3-way handshake 방식으로 연결이 종료된다.

    • FIN (클라이언트 \rarr 서버)

    • FIN + ACK (서버 \rarr 클라이언트)

      • 클라이언트 : 연결이 끊어짐

      • 서버 : 아직 연결되어 있음

    • ACK (클라이언트 \rarr 서버)

      • 클라이언트 : 연결이 끊어진 상태

      • 서버 : 연결 끊어짐

  • Half Close : 한쪽의 TCP 연결이 종료되더라도, 반대편 한쪽은 여전히 연결되어 있는 상태를 유지한다. TCP 환경에서는 양쪽의 연결을 안전하게 종료하기 위해 이러한 방식을 사용한다.

    • FIN (클라이언트 \rarr 서버) : 클라이언트가 연결을 종료하기 위해 보내는 flag이다.

    • FIN + ACK (서버 \rarr 클라이언트) : 서버는 FIN 메시지에 대해 응답을 보낸다.

      • 응답 메시지를 받은 클라이언트는 연결을 종료한다.

      • 서버는 여전히 연결을 유지한다.

    • Passive close : 서버가 보내야 할 잔여 데이터가 존재하는 등 안전한 종료를 위해 일정 시간 대기한 후, 서버가 클라이언트에게 종료 메시지를 보낸다.

    • FIN (서버 \rarr 클라이언트) : 서버가 연결 종료 신호를 클라이언트에게 보낸다.

    • ACK (클라이언트 \rarr 서버) : 클라이언트는 FIN 메시지에 대한 응답을 보낸다.

      • 서버의 연결이 종료된다.

    TCP는 위와 같은 메커니즘으로 안전한 연결 종료를 지원한다.

  • 2MSL Timer : 안전한 연결 종료를 지원하기 위해 일정 시간 고의적으로 대기 상태를 유지하도록 하는 타이머이다.

    • MSL(Maximum Segment Lifetime) : TCP 세그먼트가 네트워크 상에 존재하는 최대 시간이다.

    • 지연 패킷이 뒤늦게 도착한다던가, 잔여 데이터가 남아있다던가 등의 이유로 인해 도착할 데이터가 남아있음에도 연결이 종료되는 상황을 방지하기 위해 활용된다.

3. Flow control

  • Flow Control in TCP (흐름 제어) : TCP의 주요 기능 중 하나로, 생산자의 데이터 생성 속도와 소비자의 데이터 처리 속도 간 균형을 맞추는 메커니즘이다.

    • Control flow and feedback

      • 생산자는 데이터를 Push한다.

      • 소비자는 데이터를 처리하고, 필요하다면 흐름 제어 신호를 생산자에게 전달한다.

      • 생산자는 feedback을 통해 전송하는 데이터의 양을 조절한다.

  • 흐름 제어 예시

    • 수신자는 ACK메시지에 자신이 수용 가능한 버퍼의 크기(Receive Window size)를 기록한다.

    • 송신자는 수신자가 보낸 Receive Window size에 알맞게 자신의 Send Window size를 조절하며, 데이터를 전송한다.

4. Error control

  • Error control in TCP : TCP의 오류 제어는 데이터 전송 중 발생할 수 있는 오류를 탐지하고 수정하는 기능을 제공한다. 이는 데이터의 무결성을 보장한다.

  • 동작 예시

    • Normal Operation

      • Rule 1 : 클라이언트가 더이상 보낼 데이터가 없을 경우, ACK 메시지만 전송한다.

      • Rule 2 : ACK delay-timer는 데이터 수신 후 즉시 ACK를 보내지 않고, 일정 시간동안 전송을 지연시킨다. time-out이 발생할 경우 ACK를 전송한다.

      • Rule 3 : time-out 발생 전에 새로운 세그먼트를 수신하면, 누적 ACK를 전송하고 타이머를 다시 시작한다.

    • Case : Lost Segment

      • 전송 과정에서 한 세그먼트(seq : 701 - 800)가 손실되고, 다음 세그먼트(seq : 801 - 900)가 전송된다.

      • Rule 4 : 받을 것이라고 예상한 순서의 세그먼트가 도착하지 않았기 때문에, 받아야 할 순서의 세그먼트를 알리는 ACK를 전송한다.

      • time-out(Retransmission time-out, RTO)이 발생하고, 해당 ACK를 받은 클라이언트는 손실된 세그먼트를 재전송한다.

      • Rule 5 : 3번째 세그먼트를 정상적으로 받았기 때문에, 다음 순서 세그먼트를 담은 ACK를 클라이언트에 전송하여 정상적으로 받았음을 알린다.

    • Case : Fast retransmission

      • TCP Fast retransmission : 전송한 프래그먼트에 대해 동일한 ACK 메시지를 3번 수신하면, 즉시 해당 세그먼트를 재전송한다.
    • Case : Lost ACK

      • Rule 6 : 수신자가 중복 세그먼트를 수신할 경우, 중복 세그먼트를 폐기하며 마지막으로 보낸 ACK를 즉시 재전송하여 이미 수신한 세그먼트임을 알린다.

5. Congestion Control

  • Congestion control in TCP : TCP는 네트워크 상태를 고려하여 전송하는 데이터의 양을 조절하는 메커니즘을 통해 혼잡을 조절한다.

    • Slow start (Exponential increase)

      • 현재 네트워크 상태를 정확히 알지 못하므로 cwnd(혼잡 윈도우)의 초기 size를 1로 설정한다.

      • ACK를 수신할 때마다 cwnd의 size를 2배씩 증가시킨다.

      • 각 RTT마다 전송 가능한 세그먼트의 양이 지수적(Exponential increase)로 증가한다.

    • Congestion Avoidance (Additive increase)

      • cwnd이 혼잡 임계값(ssthresh) 근처에 도달하면, TCP는 느린 시작에서 혼잡 회피로 전환하여 동작한다.

      • 이때부터 전송되는 지수적으로 증가하던 데이터의 양(size)이 선형적으로 증가(Additive increase)한다.

TCP는 위와 같이 네트워크가 혼잡에 가까워질수록 cwnd를 섬세하게 조정하는 메커니즘을 통해 혼잡을 제어한다.

5-1. TCP Tahoe

  • TCP Tahoe : Tahoe 방식 혼잡 제어를 살펴보자.

    • 초기 설정

      • 혼잡 임계값(ssthresh)를 16 MSS로 설정

      • 느린 시작 단계에서 시작하며, cwnd는 1 MSS로 초기화된다.

    • 느린 시작 단계

      • cwnd가 지수적(2배씩)으로 증가

      • cwnd가 3 RTT에서 Time-out이 발생

      • TCP는 네트워크에 혼잡이 있다고 판단하며, ssthresh를 현재 cwnd size의 절반으로 설정(4 MSS)

      • 혼잡 윈도우의 크기를 다시 1 MSS로 초기화하고 느린 시작 상태로 복귀

      • cwnd가 다시 지수적으로 증가

    • 혼잡 회피 단계

      • cwnd가 ssthresh(4 MSS)에 도달하였기 때문에, 혼잡 회피로 전환

      • cwnd는 선형적(1씩)으로 증가

    • 3dupACKs

      • RTT 13에서 3개의 중복 ACK를 수신함 \rarr Fast Retransmission

      • ssthresh를 현재 cwnd의 절반으로 설정(6 MSS)

      • cwnd를 다시 1로 초기화하고, 느린 시작 상태로 복귀

TCP Tahoe는 위와 같은 방식으로 느린 시작과 혼잡 회피를 오가며 혼잡을 제어한다.

5-2. TCP Reno

  • TCP Reno : Reno 방식의 혼잡 제어를 살펴보자.

    • 3dupACKs 이전까지는 Tahoe와 동일하게 동작한다.

    • 3dupACKs

      • RTT 13에서 3개의 중복 ACK를 수신하였다.

      • ssthresh는 현재 cwnd의 절반인 6 MSS로 감소한다.

      • cwnd size는 ssthresh + 3 MSS로 설정되어 빠른 복구(Fast Recovery) 단계로 전환된다.

    • Fast Recovery

      • 중복 ACK를 수신했던 ssthresh까지 cwnd size를 지수적으로 증가시킨다.

      • 새로운 ACK를 수신하였기 때문에 빠른 복구 상태는 종료되며, cwnd size가 ssthresh(6 MSS)로 감소한다.

      • 혼잡 회피 단계로 전환한다.

Tahoe 방식에 비해 혼잡 구간에 가까운 구간에서 데이터를 전송하는 시간이 길다. 따라서 그만큼 네트워크 활용률이 높다.

5-3. TCP CUBIC

  • Additive increase, Multiplicative decrease(AIMD) : 네트워크 혼잡 구간까지 cwnd size를 선형적으로 증가시킨 뒤, 혼잡 구간에 도달하였을 때 cwnd size를 절반으로 감소시키는 방식으로 혼잡을 제어하는 메커니즘이다.

    • Wmax : 혼잡 손실이 발생한 순간의 전송 속도의 평균이다.

    • TCP Throughput : 0.75 * Wmax / RTT

    • TCP Throughput의 계산 결과에서 알 수 있듯이, AIMD는 혼잡 구간에 근접(75%)한 구간에서 데이터 전송을 하도록 유도하는 메커니즘이다.

  • TCP CUBIC : AIMD 기반의 TCP 혼잡 제어 방식의 한계를 개선하기 위해 제안된 알고리즘이다.

    • AIMD : 전송 속도를 혼잡 구간까지 선형적으로 증가시키며, 혼잡 발생 시 이를 절반으로 줄이며 혼잡을 제어한다.

    • CUBIC

      • 네트워크의 병목 구간의 혼잡 상태는 크게 변하지 않았을 가능성이 높다. 이는 곧 Wmax 이전의 전송 속도를 유지하면 혼잡이 발생할 가능성이 낮다는 것을 의미한다.

      • 혼잡 손실 발생 시, cwnd size를 Wmax/2로 설정한다.

      • 초기 가속 (Ramp up faster) : 감소 초반에는 cwnd size를 매우 빠르게 증가시켜 Wmax에 빠르게 근접하도록 한다.

      • 점진적 접근 (Approach more slowly) : Wmax에 가까워질수록 매우 천천히 증가하도록 전송 속도를 조절한다.

      • 마치 3차 함수와 유사한 형태를 띄게된다. 이는 선형적 증가 방식보다 효율적으로 cwnd size를 조절할 수 있다.

TCP CUBIC은 위와 같은 방식으로 Wmax에 근접한 구간에서 데이터를 전송할 수 있는 시간을 늘려 효율적으로 대역폭을 사용한다. 현재 가장 널리 사용되는 혼잡 제어 방식이다.

  • TCP CUBIC vs Reno

    • K : cwnd가 Wmax에 도달하는 순간의 시간을 나타낸다.

    • CUBIC : K에 먼 구간에선 빠르게 윈도우 크기가 증가하고, K에 가까워질수록 윈도우 크기의 증가폭이 감소한다.

    • Reno : K구간에 대한 고려 없이 선형적으로 윈도우 크기를 증가시킨다.

      • CUBIC 방식에 비해 비효율성이 크다.

6. TCP Timers

TCP는 통신의 신뢰성과 데이터 전송의 무결성을 보장하기 위해 4가지 주요 타이머를 활용한다. 각 Timer에 대해 자세히 살펴보자.

6-1. Round Trip time

  • TCP Round Trip Time (RTT) : 송신측에서 전송한 패킷이 수신측에 도달하고, 수신측이 전송한 ACK메시지가 송신측에 도달하는 데 걸리는 시간이다.

    • Tiemout은 RTT를 고려하여 적당한 값으로 설정해야 한다.

      • Timeout을 너무 짧게 설정한 경우 (Timeout < RTT) : 오류가 발생하지 않았음에도 불필요한 재전송이 자주 발생한다. 이는 네트워크 혼잡을 야기할 수 있다.

      • Timeout을 너무 길게 설정한 경우 (Timeout > RTT) : 패킷 손실에 대한 처리까지 걸리는 시간이 너무 길기 때문에, 대역폭을 효율적으로 사용하지 못하게 된다.

    • RTT 측정(추정) 방법

      • SampleRTT : 세그먼트를 전송한 시점부터 ACK를 받을 때까지 걸린 시간을 측정한 값이다.

      • SampleRTT는 네트워크 상태에 따라 조금씩 오차가 발생할 수 있으므로, 안정적인 RTT 측정을 위해 여러 SampleRTT의 평균값을 활용한다.

  • Estimate RTT : RTT는 지수 가중 이동 평균(Exponential Weighted Moving Average, EWMA) 방식으로 측정된다.

    EstimatedRTT=(1α)EstimatedRTT+αSampleRTTEstimatedRTT = (1-\alpha)*EstimatedRTT + \alpha*SampleRTT
    • α\alpha : 가중치, 일반적으로 0.125로 설정

    • EstimatedRTT : 현재 까지의 RTT 측정값

    • SampleRTT : 가장 최근 샘플의 RTT 값

      • RTT 측정 값에 가중치를 크게 두고 가장 최근 샘플 RTT 값의 가중치를 적게 두어 네트워크 상태 변화를 반영하면서도 RTT 값의 급격한 변화(오차)를 완화하여 평균에 반영하는 방식이다.
  • Timeout Interval : 데이터 재전송을 위해 설정하는 timeout 값으로, EstimatedRTT에 Safety margin을 추가한 값으로 설정한다.

    TimeoutInterval=EstimatedRTT+4DevRTTTimeoutInterval = EstimatedRTT + 4*DevRTT
    • Timeout Interval은 항상 EstimatedRTT보다 크거나 같아야한다.

    • 네트워크 상태에 따라 변화하는 RTT의 특성을 고려하여, 안전 마진을 설정한다.

    • DevRTT : 안전 마진은 다음과 같이 계산된다.

      DevRTT=(1β)DevRTT+βSampleRTTEstimatedRTTDevRTT = (1-\beta)*DevRTT + \beta*|SampleRTT - EstimatedRTT|
      • β\beta는 가중치이며, 일반적으로 0.25로 설정한다.

      • RTT의 변동성을 측정하기 위해 SampleRTT와 EstimatedRTT간의 차이를 반영한다.

      • RTT를 측정하는 방식과 유사한 방식으로 계산된다.

  • Timeout 계산 예제

    • SYN 세그먼트 전송

      • RTT, SRTT(Smoothed RTT), RTTVAR(RTT Variance) 값이 아직 측정되지 않음

      • 초기 RTO(Retransmission Timeout)을 기본값인 6.00초로 설정

    • SYN + ACK 도착

      • RTT : 1.5초로 측정됨

      • SRTT : 첫 번째 측정 값이므로, RTT와 동일하게 설정

      • RTTVAR : 1.52=0.75\frac{1.5}{2} = 0.75

      • RTO : SRTT+4RTTVAR=4.5SRTT + 4 * RTTVAR = 4.5

    • 데이터 전송 및 ACK 수신

      • RTT : 2.5초로 측정

      • SRTT : (1α)SRTT+αRTT=781.5+182.5=1.625(1-\alpha)*SRTT + \alpha*RTT = \frac{7}{8}*1.5 + \frac{1}{8}*2.5 = 1.625

      • RTTVAR : (1β)RTTVAR+βRTTSRTT=340.75+142.51.625=0.78(1-\beta)*RTTVAR + \beta|RTT - SRTT| = \frac{3}{4}*0.75 + \frac{1}{4}*|2.5 - 1.625| = 0.78

      • RTO : SRTT+4RTTVAR=4.74SRTT + 4*RTTVAR = 4.74

  • TCP 재전송 예제 (Karn's Algorithm)

    • 세그먼트가 전송되었지만 손실

    • RTO 만료 후 해당 세그먼트가 재전송 됨

    • 재전송 후 RTO가 2배로 증가하여 9.48초가 됨

    • 재전송 패킷에 대한 ACK를 수신하였지만, Karn's Algorithm에 따라 RTO 재계산을 생략함.

      • Karn's Algorithm은 재전송된 패킷의 RTT 측정을 제외함으로써, 잘못된 RTT를 측정을 방지한다.

      • 재전송된 패킷의 ACK를 통해 측정된 RTT는 일반적인 RTT와 오차가 클 가능성이 높기 때문이다.

    • 새로운 세그먼트 전송 후 RTO 계산

6-2. Persistent Timer

  • Persistent Timer : zero-window-size로 인해 발생할 수 있는 Deadlock을 해결하기 위해 사용되는 타이머이다.

    • Deadlock : 수신 측이 rwnd(수신 윈도우) size를 0으로 설정하여 송신측이 더이상 데이터를 보내지 않는 상황

      • 수신측이 다시 윈도우 크기를 증가시키더라도, 수신측이 이를 알릴 방법이 없다.

      • 송신측은 이를 감지하지 못하기 때문에 양측 모두 대기하는 Deadlock에 빠진다.

    • Persistent Timer : 송신측이 rwnd size = 0인 ACK를 수신하면, persistent timer를 설정한다.

      • 타이머가 만료될 경우, 송신측은 Probe Segment를 전송한다.

      • Probe Segment : 1바이트의 새 데이터를 포함하고 있으며, 수신측 상태를 확인하기 위한 세그먼트이다.

      • 수신측은 Probe Segment에 대한 ACK를 전송하며, 현재 업데이트된 윈도우 크기를 송신측에 알린다.

      • 만약 수신측의 버퍼가 비워져 rwnd가 0이 아니라면, 송신측은 데이터를 다시 전송한다.

6-3. Keep-Alive Timer

  • Keep-Aliver Timer : 클라이언트와 서버가 연결된 후, 오랫동안 비활성 상태(Idle)가 유지되는 것을 방지하기 위해 사용되는 타이머

    • 클라이언트와 서버가 TCP Connection이 되어있는데, 침묵 상태가 유지될 경우

    • 혹은 클라이언트가 비정상적으로 종료되었지만, 서버가 이를 감지하지 못하는 경우

    • Timer 동작

      • 서버는 클라이언트로부터 데이터를 수신할 때마다 Timer를 재설정(보통 2시간)한다.

      • Timeout이 발생하면, 서버는 클라이언트에게 Probe Segment를 전송한다.

      • 클라이언트가 응답할 경우, 연결은 유지된다.

      • 응답이 없을 경우, 서버는 Probe Segment를 75초 간격으로 10번 전송한다.

      • 여전히 응답이 없을 경우, 연결을 종료한다.

6-4. Time-Wait Timer

  • Time-Wait Timer : 두 번째 FIN 메시지를 수신하였을 때, 연결을 종료하면서 Time-Wait Timer를 설정한다.

    • TCP 연결이 종료된 후에도 지연된 패킷이 도착할 수도 있다.

    • 새로운 연결이 이전 연결과 동일한 포트를 사용할 경우, 지연 도착한 패킷들이 다음 연결에 영향을 미칠 수도 있다.

    • 위와 같은 상황들을 방지하기 위해 Time-Wait Timer를 사용하며, 일반적으로 2MSL(Maximum Segment Lifetime)으로 설정한다.

profile
한량 극복 프로젝트

0개의 댓글