TCP(Transmission Control Protocol)

대문 / 네트웍, 프로그래밍 / TCP(Transmission Control Protocol)

TCP(Transmission Control Protocol)

1.1. 개요

TCP Header Format
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Description
16-bit Source Port (출발지 포트 번호) 16-bit Destination Port (목적지 포트 번호) ↑↓20 bytes ↑↓20~60 bytes
32bit Sequence Number (순번)
32bit Acknowledgment Number (예측 순번, ACK flag 가 설정된 경우)
4-bit Data Offset (TCP Header length) 3-bit Reserved (0 0 0) 1-bit NS 1-bit CWR 1-bit ECE 1-bit URG 1-bit ACK 1-bit PSH 1-bit RST 1-bit SYN 1-bit FIN 16-bit Window Size
16-bit Checksum 16-bit Urgent Pointer
Variable-size Options (Data Offset 값이 5보다 큰 경우, Options의 마지막이 32bits로 정렬되기 위해서 padding을 포함할 수 있음.) Padding ↑↓0~40 bytes
Variable-size Data ↑↓ Total length - Header length(Data Offset)
  • Source Port: 16bits
    • 송신(출발지) 포트 번호
  • Destination Port: 16bits
    • 수신(목적지) 포트 번호
  • Sequence Number: 32bits
    • SYN flag 가 설정(1)된 경우 초기 순번(ISN: Initial Sequence Number)이 됩니다. 실제 Data의 첫번째에서 이 값은 1을 더한 값이 됩니다.
      • 양방향통신시 각 방향 마다 다른 ISN 번호가 사용됩니다.
    • SYN flag 가 해제(0)된 경우 현재 Session에서의 현재 Segment data의 누적 순번이 됩니다.
    • 임의 값으로 시작하여, 최대값(4,294,967,295 : 2의 32승 최대치) 이후에는 overflow 되어 0으로되어 시작함
    • TCP Segment의 첫번째 byte에 부여되는 번호로써 사용됨.
  • Acknowledgment Number: 32 bits
    • ACK flag 가 설정(1)된 경우 수신자가 예상하는 다음 순번을 나타냅니다.
      • 수신하기를 기대하는 다음 바이트 번호 (즉, 마지막으로 수신한 번호에 +1을 한 값)
  • Data Offset (TCP Header length): 4 bits
    • TCP payload data 의 위치를 의미합니다. 다르게 표현하면 TCP Header의 크기를 의미한다고 할 수도 있습니다.
      • TCP Header의 최소 크기는 20 bytes(워드 단위 값 5) 이며, 최대 크기는 60 bytes(워드 단위 값 15) 입니다. (즉, Options는 최대 40 bytes를 추가할 수 있다는 의미)
      • 32-bit 워드(word) 단위의 값을 사용합니다. (즉, 20 bytes 라면 20 bytes/ 32 bits = 20 bytes / 4 bytes = 5 words)
        • 즉, 1 word 는 4 bytes(32-bits)
        • 나타날 수 있는 값의 범위는 5 ~ 15
      • Options 가 32-bit로 정렬되어야 하는 이유이기도 합니다. Options는 정렬을 위해서 padding을 포함할 수 있습니다.
  • Reserved: 3 bits
    • 미래를 위한 예약 영역이며 0으로 채워져야 합니다.
  • Control Bits: 6 bits (from left to right):
    • NS: ECN-nonce (은폐 보호, [https]RFC3540 - Robust Explicit Congestion Notification (ECN) Signaling with Nonces[](https://tools.ietf.org/html/rfc3540))
    • CWR: Congestion Window Reduced (혼잡 윈도우 축소, [https]RFC3168 - The Addition of Explicit Congestion Notification (ECN) to IP[](https://tools.ietf.org/html/rfc3168))
    • ECE: ECN-Echo ([https]RFC3168 - The Addition of Explicit Congestion Notification (ECN) to IP[](https://tools.ietf.org/html/rfc3168))
    • URG: Urgent Pointer field significant (Urgent Pointer 필드에 값이 채워져있음을 알림)
      • Urgent flag는 클라이언트가 서버에게 (혹은 그 반대의 경우) 현재의 TCP flow와는 상관없는 일을 시키고 싶을때 사용합니다.
      • Urgent flag는 소켓옵션으로 MSG_OOB(Out of band)을 통해서 설정할 수 있습니다.
      • Urgent flag를 받으면 수신측 응용프로그램은 SIGUSR signal을 받을 수 있습니다.
    • ACK: Acknowledgment field significant (Acknowledgement Number 값이 셋팅됐음을 알림)
    • PSH: Push Function (수신측은 버퍼가 찰 때까지 기다리지 않고 데이타를 가능한한 빨리 상위 계층 응용프로그램에 즉시 전달할 것을 알림)
    • RST: Reset the connection (강제적인 의미로써 연결 초기화를 알림)
    • SYN: Synchronize sequence numbers (연결시작, 초기화를 위한 순서번호의 동기화)
    • FIN: No more data from sender (연결해제, 송신기가 데이타 보내기를 끝마쳤음을 알림, 연결을 종료하고 싶다는 의사를 알림)
  • Window: 16 bits
    • 수신 윈도우의 크기 (해당 Segment의 송신측이 현재 수신하고자 하는 윈도우 크기)
      • cwnd (Congestion window) : 송신자 측에서 전달하는 윈도우 크기
      • rwnd (Received window) : 수신자 측에서 제공하는 윈도우 크기
      • Sliding Window : 수신측에서 설정한 윈도우 크기만큼 송신 측에서 확인 응답 (Ack) 없이 전송 할 수 있게 흐름을 동적으로 조절하는 제어 알고리즘
    • Octet(Byte) 단위로 나타냅니다.
    • Acknowledgment Number의 순번보다 큰 값이어야 합니다.
  • Checksum: 16 bits
    • 참고: Computing the Internet Checksum (RFC1071)
    • 주어진 checksum 영역 Pseudo header(의사 헤더)에 대한 합을 16bits로 산출하는데 overflow 되는 값은 1의 보수로 합하는 구현을 의미합니다. (Computing the Internet Checksum (RFC1071))
    • Pseudo header(의사 헤더)는 실제로는 존재하지 않지만 checksum 계산시에 IP header의 일부 정보가 병합되어사용되는 가상의 헤더임
      • IPv4의 경우 12 bytes(96-bits) "Pseudo header(의사 헤더)" + "TCP Header" + "Payload Data"에 대한 checksum을 계산한 값입니다.
        • Pseudo header format (IPv4 인 경우, [https]RFC793 Section-3.1[](https://tools.ietf.org/html/rfc793#section-3.1))
          Pseudo header format (IPv4)
          0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Description
          32-bit Source Address ↑↓8 bytes ↑↓12 bytes
          32-bit Destination Address
          8-bit Zero 8-bit PTCL(Protocol) 16-bit TCP Length (TCP Header + Data) ↑↓4 bytes
      • IPv6의 경우 40 bytes(320-bits) "Pseudo header(의사 헤더)" + "TCP Header" + "Payload Data"에 대한 checksum을 계산한 값입니다.
        • Pseudo header format (IPv6 인 경우, [https]RFC2460 Section-8.1[](https://tools.ietf.org/html/rfc2460#section-8.1))
          Pseudo header format (IPv6)
          0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Description
          128-bit Source Address ↑↓32 bytes ↑↓40 bytes
          128-bit Destination Address (Final destination address)
          32-bit Upper-Layer Packet Length ↑↓4 bytes
          24-bit Zero 8-bit Next Header ↑↓4 bytes
    • UDP도 동일한 Pseudo header(의사 헤더)를 취하여 checksum을 계산합니다.
  • Urgent Pointer: 16 bits
    • URG flag가 설정(1)된 경우, 순번으로부터의 위치(Offset)을 나타냅니다. 이 위치(Offset)가 마지막 긴급 데이터 바이트를 가리키게 됩니다.
      • 현재 Sequence number로부터 긴급 데이터까지의 octet offset
      • Segment의 Sequence number에 Urgent point 값을 더하면 긴급 데이터의 끝을 가르킵니다.
    • URG flag가 해제(0)된 경우, 이 값은 유효하지 않습니다.
  • Options: variable
    • 하나의 Option은 "TYPE(1bytes) + LEN(1bytes) + OPTDATA(n)" 와 같은 형태로 여러개의 Option을 추가할 수 있습니다. (Options의 총 크기는 최대 40 bytes 를 넘을 수 없으며 32bits 로 정렬되기 위해서 padding을 포함할 수 있습니다.)
      • TYPE
        • TCPOPT_EOL(0): End of options
          • TCPOLEN_EOL: 1 byte
        • TCPOPT_NOP(1): Padding
          • TCPOLEN_NOP: 1 byte
        • TCPOPT_MSS(2): Segment size negotiating
          • TCPOLEN_MSS: 4 bytes
          • IPv4에서 MSS option이 주어지지 않는 경우 MSS는 536 octets 으로 간주 하도록 합니다. (최소 MTU를 576으로 간주하고 계산하는 정의, 576 - 20 - 20)
          • IPv4에서 MTU 1500 기준으로 최대 MSS크기는 1460 octets (1500 - 20 - 20) 이 가능합니다.
          • IPv6에서 MSS option이 주어지지 않는 경우 MSS는 1220 octets 으로 간주 하도록 합니다.
          • IPv6에서 MTU 1500 기준으로 최대 MSS크기는 1440 octets (1500 - 40 - 20) 이 가능합니다.
          • MSS값은 자신의 MTU보다는 작게 설정하는 것이며 중간 네트워크 구간을 고려하여 Path MTU 보다 작게 고려되는 값이어야 합니다.
            • 일부 네트워크 장비들은 Path MTU를 감지하는데 문제를 가지고 있는 경우도 있어 이 때는 MSS 값을 수동으로 조정해야 할 수 있습니다. (DF flag 가 설정된 패킷을 무시하고 Fragmentation 하여 전송하는 등)
          • 패킷 흐름 중간에 Encapsulation 계층의 터널 (예: IPSecVPN 등)이 존재하는 경우 이 값이 조정될 수 있습니다.
            • IPSecVPN에서 AES-256 with SHA-1 기준)을 기준으로 ESP Header+Trailer size는 73 bytes 이며 IPv4에서 MTU 1500인 경우 최대 MSS크기는 1387 octets가 됩니다. 하지만 실제 최대 MSS크기는 1388 octets가 가능합니다.
              • 확실한 이해를 위해서는 Linux kernel의 esp4_get_mtu() 함수를 반드시 이해하면 도움이 됩니다. (주어진 실제 MTU로부터 ESP Overhead를 계산해서 MTU에 반영해주는 함수) Data는 가변이기 때문에 결국 최대 가능한 padding 크기일때를 기준으로 MSS를 계산해야 합니다.
                • Size of Initialazation Vector for
                  • AES: 16 bytes
                  • DES: 8 bytes
                • Size of Authentication Data for
                  • MD5: 12 bytes
                  • SHA-1: 12 bytes
                  • SHA-256: 16 bytes
                  • SHA-384: 24 bytes
                  • SHA-512: 32 bytes
                • Maximum Size of padding for
                • Size of ESP Header for 16(ESP Header size) = 4(SPI) + 4(Sequence) + 8(IV, RFC3686)
                • Size of ESP Trailer for 14~(ESP Trailer size) = 0~255(4 bytes aligned for) + 1(Padding length) + 1(Next Header) + 12(Authentication data, SHA-1)
                • minimum 72 bytes = 16(ESP Header) + 20(inner IP Header) + 20(TCP Header) + x(Data) + 14~(ESP Trailer)
        • TCPOPT_WINDOW(3): Window scaling (주어진 Window size 보다 더 크게 사용하고자 할 때)
          • TCPOLEN_WINDOW: 3 bytes
        • TCPOPT_SACK_PERM(4): SACK Permitted
          • TCPOLEN_SACK_PERM: 2 bytes
        • TCPOPT_SACK(5): SACK Block (Selective Acknowledgement, 선택확인응답, 여러 세그먼트 중 손실된 세그먼트 만 선택적으로 확인응답하는 방식)
        • TCPOPT_TIMESTAMP(8): Better RTT estimations/PAWS
          • TCPOLEN_TIMESTAMP: 10 bytes
        • TCPOPT_MD5SIG(19): MD5 Signature (RFC2385)
        • TCPOPT_COOKIE(253): Cookie extension (experimental)
          • TCPOLEN_COOKIE_BASE: 2 (Cookie-less header extension)
          • TCPOLEN_COOKIE_PAIR: 3 (Cookie pair header extension)
          • TCPOLEN_COOKIE_MIN: (TCPOLEN_COOKIE_BASE+TCP_COOKIE_MIN)
            • TCP_COOKIE_MIN: 8 bytes (64-bits)
          • TCPOLEN_COOKIE_MAX: (TCPOLEN_COOKIE_BASE+TCP_COOKIE_MAX)
            • TCP_COOKIE_MAX: 16 bytes (128-bits)
        • TCPOPT_EXP(254): Experimental
          • TCPOPT_FASTOPEN_MAGIC(0xF989): Magic number to be after the option value for sharing TCP (experimental options. See draft-ietf-tcpm-experimental-options-00.txt)
            • TCPOLEN_EXP_FASTOPEN_BASE: 4
      • LEN: TYPE + LEN + OPTDATA를 합한 크기 (참고: [https]https://www.freesoft.org/CIE/Course/Section4/8.htm[])
        • TYPE이 TCPOPT_NOP과 TCPOPT_EOL인 경우는 예외적으로 LEN과 OPTDATA가 없으며 그 외의 TYPE은 모두 적어도 LEN은 2 이상의 값이어야 하며 LEN이 2인 경우는 OPTDATA가 없음을 의미합니다.
    • Data offset의 값이 5인 경우는 Options와 Padding이 없음을 의미합니다.
    • Options + Padding 의 크기(bytes)는 (Data offset - 5) * 4 으로 계산할 수 있습니다.
  • Padding: variable
    • TCP Header의 마지막 부분은 32bit로 정렬되어야 하기 위함. (Options의 마지막이 32bit로 정렬하기 위함)
    • Padding에 채워지는 값은 0입니다.

1.2. TCP 상태 천이도 (TCP state diagram)

Tcp state diagram fixed new
참고 이미지
1084px-Tcp_state_diagram_fixed_new.svg.png
[PNG image (69.29 KB)]
이미지 출처: [https]https://en.wikipedia.org/wiki/File:Tcp_state_diagram_fixed_new.svg[]

  • LISTEN
    • (Server) Waiting for a connection request from any remote TCP end-point.
  • SYN-SENT
    • (Client) Waiting for a matching connection request after having sent a connection request.
  • SYN-RECEIVED
    • (Server) Waiting for a confirming connection request acknowledgment after having both received and sent a connection request.
  • ESTABLISHED
    • (Server and client) An open connection, data received can be delivered to the user. The normal state for the data transfer phase of the connection.
  • FIN-WAIT-1
    • (Server and client) Waiting for a connection termination request from the remote TCP, or an acknowledgment of the connection termination request previously sent.
  • FIN-WAIT-2
    • (Server and client) Waiting for a connection termination request from the remote TCP.
  • CLOSE-WAIT
    • (Server and client) Waiting for a connection termination request from the local user.
  • CLOSING
    • (Server and client) Waiting for a connection termination request acknowledgment from the remote TCP.
  • LAST-ACK
    • (Server and client) Waiting for an acknowledgment of the connection termination request previously sent to the remote TCP (which includes an acknowledgment of its connection termination request).
  • TIME-WAIT
    • (Server or client) Waiting for enough time to pass to be sure that all remaining packets on the connection have expired.
  • CLOSED
    • (Server and client) No connection state at all.

1.3. TCP 연결 수립

  • three-way (or 3-step) handshake
    1. SYN : TCP Client 는 TCP Server 로 SYN 을 전송.
      • 초기 순번(ISN: Initial Sequence Number) A 는 임의의 초기 값으로 결정하여 전송
    2. SYN + ACK : TCP Server는 TCP Client 로 SYN + ACK 으로 응답.
      • 이 때 Acknowledgment Number는 TCP Client로부터 받은 초기 순번(ISN: Initial Sequence Number)에 1을 더한 A + 1 값으로 응답
      • Sequence Number는 임의의 다른 값 B로 결정하여 응답
    3. ACK : TCP Client는 TCP Server 로 ACK 응답으로 연결 수립을 알림.
      • Sequence Number는 TCP Server로부터 받은 Acknowledgment Number인 A + 1 값으로 응답
      • Acknowledgment Number는 TCP Server로부터 받은 Sequence Number에 1을 더한 B + 1 값으로 응답
      • 선택적으로 TCP Client는 ACK + PSH로 Request payload data를 함께 전송하기도 함.

1.4. TCP 연결 종료

  • four-way handshake : 연결 종료는 각자 FIN을 전송하고 그에 대한 응답 ACK를 받는 흐름)
    1. FIN : 연결 종료을 시작하는 쪽에서 FIN을 전송
    2. ACK : FIN을 받은 쪽에서 ACK응답
    3. FIN : 연결 종료를 받은 쪽에서 FIN을 전송
    4. ACK : 연결 종료를 시작한 쪽에서 최종 ACK를 전송
  • three-way (or 3-step) handshake
    1. FIN : 연결 종료을 시작하는 쪽에서 FIN을 전송
    2. ACK+FIN : FIN을 받은 쪽에서 ACK + FIN 응답
    3. ACK : 연결 종료를 시작한 쪽에서 최종 ACK를 전송
  • half-duplex close sequence
    1. FIN 대신에 RST를 전송하여 연결을 종료
    2. 더이상 아무것도 전송하는 것 없이 종료 처리되어야 함.

1.5. TCP 흐름 제어

  • 수신측이 주도적으로 rwnd (Received window) 값을 결정
    • 수신측은 송신측에게 자신의 가능한 수신 버퍼 상태(rwnd)를 알리는 방법
    • 수신측은 ACK(확인응답)을 보내면서 현재의 수신 윈도우 크기를 함께 보내게됨

1.6. TCP 혼잡 제어

  • 네트워크 혼잡 상황에 따라 cwnd (Congestion window) 값 결정
    • Network가 혼잡하다는 징후가 증가할 때 전송량을 줄이고, 혼잡이 줄어들 때 다시 전송량을 늘리는 것.

1.7. TCP 최대 Segment size 결정

  • TCP payload size = "IP header Total Length" - "IP Header Length" - "TCP Header Length"
  • 적정 TCP Segment size = min(송신 버퍼 크기, 수신 버퍼 크기, MTU size, path MTU size) - "Header size"
  • TODO
    • GSO, TSO, LRO, ...

1.8. TCP Window scaling

TODO

1.9. TCP OOB(Out of band) data

TODO

1.10. 참고자료

Retrieved from https://www.minzkn.com:443/moniwiki/wiki.php/TCP
last modified 2023-02-14 11:40:01