[ch3] 5. connection-oriented transport: TCP

    1. TCP: Overview

    • Connection-oriented: 데이터 전송 전, sender와 receiver는 연결을 해야 함. Logical end-to-end connection
    • Point-to-Point: 한 연결당 하나의 sender와 receiver
    • Full duplex data: 한 연결에 양방향 통신 가능
    • Flow controlled: sender는 receiver가 받을 수 있는 데이터 양보다 많이 보내면 안됨
    • Reliable data transfer: 100% or 0% 전송
    • in-order delivery:receiver는 sender가 보낸 순서대로 받음
    • Segment/Byte-stream
      • client는 byte stream을 socket으로 보냄
      • TCP는 이 데이터를 send buffer에 저장 후, segment로 만들어서 network layer로 전송
      • MSS: Maximum Segment Size
        • MTU: Maximum Transmission Unit, 전송 가능한 최대의 link-layer frame
        • MSS는 MTU가 결정될 때 결정됨
        • MSS = TCP header + TCP segment
    • Pipelined: Congestion control과 flow control은 동적인 window size를 가짐

     

    2. Many flavors of TCP

    • TCP의 역사
      • TCP Tahoe
      • TCP (new) Reno: 수업시간에 공부할 TCP
      • TCP Vegas
      • TCP Westwood
      • TCP BIC
      • TCP CUBIC
      • ...
    • 주요 차이는 Congestion Control Algorithm

     

    3. TCP segment structure

    • TCP header
      • source port #
      • dest port #
      • seq #: byte를 단위로 셈
      • ack #: byte를 단위로 셈
      • head length: header 길이
      • U: urgent data
      • A: ACK # valid
      • P: push data now
      • R, S, T: RST, SYN, FIN
        • Connection을 만들고 disconnect할 때 사용
      • Receiver window: receiver가 받을 수 있는 byte 수(버퍼의 빈공간)로 flow control에 사용됨
      • checksum
      • Urg data pointer
    • TCP payload
      • application data

     

    4. TCP sequence numbers, ACK numbers

    • 예시1) 500KB 메시지를 보내는데, MSS가 1000 bytes
      • sender가 1st segment를 receiver에게 보내면, receiver는 ack로 1000을 sender에게 보냄 
    • seq #: segment의 첫번째 byte의 byte stream number
      • 첫번째 segment의 seq #로 0을 사용하지 않음. 랜덤 number 사용. 같은 숫자를 사용하면 receiver가 혼동할 수 있기 때문임.
      • seq #의 시작 숫자는 연결이 설정될 때 알 수 있음. 송신자와 수신자가 서로에게 이야기 함
    • ack #: 상대방에게 받을 것이라 기대되는 다음 byte의 sequence #
    • packet은 seq #, ack #를 동시에 가짐 (full duplex)
    • receiver가 out-of-order segments를 다루는 것은 구현하는 사람이 결정함. TCP spec이 결정하지 않음

     

    • 예시2) HOST A가 'C'라는 데이터를 보내면 HOST B도 받은 데이터 그대로를 A에게로 보냄 
      • 1. A, B 간 연결 설정
        • A의 seq #의 시작 숫자가 42로 결정됨
        • B의 seq #의 시작 숫자가 79로 결정됨
      • 2. A가 B에게 'C'를 보냄
        • ACK: B에게 받을 것이라고 예상되어지는 byte
      • 3. B는 A에게 'C'를 받고 다시 'C'를 보냄
        • ACK: A에게 받을 것이라고 예상되어지는 byte
        • B가 'C'를 다시 보내는 것은 A에게 데이터 잘 받았다~ 하는 ACK 용도도 존재
      •  4. A는 B에게 ACK 용도로 다시 데이터를 보냄

     

    5. TCP round trip time, timeout

    • TCP는 timeout때 까지 ack가 안오면 packet loss가 생긴 것이기 때문에 데이터를 재전송함
    • timeout을 설정하는 법?
      • RTT보다 길게 설정해야함
        • RTT보다 길긴 한데 너무 짧으면, timeout이 쓸데없이 많이 발생해서 재전송이 많이 일어나고
        • RTT보다 너무 길면, packet loss에 느리게 대응해 slow, low throughput
        • 둘 다 안좋다!
      • timer를 얼마나 많이 두어야 하는가? 한 윈도우 안의 모든 패킷에 timer를 두어야하는가?
    • RTT 추정방법
      • SampleRTT: ACK가 도달할 때까지 segment 전송시간을 측정
        • 재전송은 무시함
        • pipleline 방식을 사용해서 packet 여러개를 동시에 보내지만, RTT당 하나의 SampleRTT를 대략적으로 측정
      • overfit된 SampleRTT말고 smoother한 RTT를 원함. 그래서 마지막에 측정한 여러 개의 값들을 평균내서 사용
    • Exponential Weighted Moving Average (EWMA)
      • EstimatedRTT = (1-a) * EstimatedRTT + a * SampleRTT
        • SampleRTT: 가장 최근에 잰 측정값
        • 측정된 RTT가 쌓여갈수록 예전 측정값의 영향이 빠르게 줄어듦
        • a는 주로 0.125를 사용함
    • Timeout interval: EstimatedRTT + 'safety margin' 
      • SampleRTT의 편차가 클수록 safety margin이 커야함

    • SampleRTT의 편차를 추정해보자
      • DevRTT = (1-B)*DevRTT + B*|SampleRTT-EstimatedRTT|
        • |SampleRTT-EstimatedRTT|: 제일 최근 편차
        • B는 주로 0.25를 사용함
    • TimeoutInterval = EstimatedRTT + 4*DevRTT
      • 4*DevRTT: safety margin

     

    6. TCP reliable data transfer

    • IP는 unreliable함. queue overflow나 out-of-order이 발생해서 데이터가 drop되거나 lost될 수 있음
    • TCP는 IP 위에서 reliable한 data transfer를 지원함
      • 수신된 byte stream은 정확하게 수신됨
      • Pipeline segements, 누적 ack, 하나의 재전송 timer 사용
      • 재전송은 timeout이 발생하거나 duplicate ack가 도달 시 발생함
    • 예시)
      • duplicate ack, flow control, congestion control을 무시함
      • 한 명의 송신자가 한 명의 수신자에게 데이터를 전송한다고 가정
      • 송신자
        • 1. app으로부터 데이터를 받아서 seq #를 가진 segment를 만듦. timer가 돌아가고 있지 않다면 timer를 start함. 가장 오래된 unacked segment에 timer가 존재해야함. TimoutInterval = EST_RTT + 4*DEVRTT
        • 2-1. Timeout이 발생하면 segment를 재전송하고 timer를 재시작함. 이 때 timeout interval를 2배로 늘림
          • 보통 network가 혼잡할 때 일어남. 재전송을 하면 혼잡한 네트워크를 더 혼잡하게 만듦. 그래서 ACK가 느리게 도착할 수 밖에 없기 때문에 timeout를 두 배로 늘림
        • 2-2. ACK를 받았다
          • ACK가 unacked segment에 대한 ack라면, seq #를 업데이트 하고 unacked segment에 대하여 timer를 재시작함
          • ACK가 이전에 받았던 segment에 대한 ack라면, duplicate ack임

     

    7. TCP ACK generation

    Event at receiver TCP receiver action
    예상하고 있었던 segment가 순서에 맞게 도착했다. 예상하고 있었던 seq #까지 모든 데이터가 이미 ACK 상태이다. ACK 전송을 미룸. 너무 많은 ACK도 네트워크를 혼잡하게 만들 수 있기 때문. 다음 segment가 도착할 때 까지 500ms를 기다리고, 안오면 ACK 전송
    예상하고 있었던 segment가 순서에 맞게 도착했다. 근데 한 segment에서 ACK를 못받은 상태이다. 바로 이때까지 멀쩡하게 온 segment에 대해 (방금 온것도 포함) cumulative ACK를 전송함.
    예상하고 있었던 segment보다 높은 seq #의 segment가 순서에 맞지 않게 도착했다.  duplicate ACK를 전송함. 다음에 받을 것이라고 예상되는 seq #를 나타냄
    도착한 segment가 빵구난 부분을 채움 ACK를 보냄.

     

    8. TCP fast retransmit

    • 문제: Timeout period는 종종 길어서 lost packet을 보낼때까지 오랜 시간이 지연된다.
    • 아이디어: duplicate ACK를 통해 lost segment를 찾자
      • 송신자는 많은 segement를 종종 연속해서 보냄. segment가 lost되면, duplicate ACK가 발생될 것임
    • TCP fast retransmit
      • 만약 송신자가 같은 데이터에 대해 3개의 ACK를 받으면,
      • 가장 오래된(가장 작은 seq #를 가진) unacked segment를 재전송

     

    9. TCP flow control

    • 송신자는 데이터를 너무 빨리 전송하면 안됨
      • buffer가 가득차서 overflow가 생길 수 있음
    • 수신자는 송신자가 수신자의 버퍼를 넘길 만큼 데이터를 빠르게 보내게 해서는 안됨
    • 수신자는 TCP header에 rwnd라는 값을 포함시켜서 buffer에 빈 공간을 알림
      • RcvBuffer 사이즈는 socket option을 통해 설정됨 (default: 4096 bytes)
      • 많은 OS는 RcvBuffer 사이즈를 자동으로 증가, 감소시킬 수 있음
    • 송신자는 receiver의 rwnd value를 보고 unacked data 양을 제한함
    • receive buffer에서 oveflow가 발생하지 않도록 보장

     

    10. TCP connection management

    • 통신 전에, sender/receiver는 연결을 설정함
      • 서로 통신하는 것에 동의
      • seq #의 시작점, rcvBuffer size 등의 connection variables 교환
    • 연결 설정에 동의하는 방법
      • 2-way handshake: server는 client가 메시지를 받았는지 모름
      • 3-way handshake
        • 1. 클라이언트는 서버에게 TCP SYN msg 전송
          • SYNbit 1로 설정, random으로 정한 seq# x를 전송
        • 2. 서버가 제대로 데이터를 받았으면, TCP SYNACK 메시지를 만들어서 전송
          • SYNbit, ACKbit 1로 설정, 랜덤으로 정한 seq# y 전송, ACK #=x+1
        • 3. 클라이언트가 서버에게서 SYNACK 메시지를 제대로 받았으면, 이 때부터 연결이 설정된 것임. ACK 메시지 전송
          • ACKbit 1로 설정. ACK #=y+1

    • TCP: closing a connection
      • 1. 클라이언트는 소켓을 닫고, FINbit를 1로 설정해서 보냄
      • 2. 서버는 ACK를 보냄. 하지만 아직 연결을 끊은 것은 아님
      • 3. 클라이언트는 서버도 종료하기를 기다림
      • 4. 일정 시간이 지나고, 서버도 연결을 종료하려고 함. 그래서 FINbit를 1로 설정해 클라이언트에게 보냄
      • 5. 클라이언트는 ACKbit를 보내고, 2배의 segment lifetime만큼 기다려줌
      • 6. 서버는 클라이언트에게서 ACK를 받으면 연결을 종료시킴
      • 7. 클라이언트는 서버에게서 아무것도 오지 않은 채 timeout이 지나면 종료

    댓글

    1. 1. TCP: Overview
    2. 2. Many flavors of TCP
    3. 3. TCP segment structure
    4. 4. TCP sequence numbers, ACK numbers
    5. 5. TCP round trip time, timeout
    6. 6. TCP reliable data transfer
    7. 7. TCP ACK generation
    8. 8. TCP fast retransmit
    9. 9. TCP flow control
    10. 10. TCP connection management