1.1. 개요
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에 부여되는 번호로써 사용됨.
- SYN flag 가 설정(1)된 경우 초기 순번(ISN: Initial Sequence Number)이 됩니다. 실제 Data의 첫번째에서 이 값은 1을 더한 값이 됩니다.
- Acknowledgment Number: 32 bits
- ACK flag 가 설정(1)된 경우 수신자가 예상하는 다음 순번을 나타냅니다.
- 수신하기를 기대하는 다음 바이트 번호 (즉, 마지막으로 수신한 번호에 +1을 한 값)
- ACK flag 가 설정(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을 포함할 수 있습니다.
- TCP payload data 의 위치를 의미합니다. 다르게 표현하면 TCP Header의 크기를 의미한다고 할 수도 있습니다.
- Reserved: 3 bits
- 미래를 위한 예약 영역이며 0으로 채워져야 합니다.
- Control Bits: 6 bits (from left to right):
- NS: ECN-nonce (은폐 보호, RFC3540 - Robust Explicit Congestion Notification (ECN) Signaling with Nonces)
- CWR: Congestion Window Reduced (혼잡 윈도우 축소, RFC3168 - The Addition of Explicit Congestion Notification (ECN) to IP)
- ECE: ECN-Echo (RFC3168 - The Addition of Explicit Congestion Notification (ECN) to IP)
- 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의 순번보다 큰 값이어야 합니다.
- 수신 윈도우의 크기 (해당 Segment의 송신측이 현재 수신하고자 하는 윈도우 크기)
- 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 인 경우, 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
- Pseudo header format (IPv4 인 경우, RFC793 Section-3.1)
- IPv6의 경우 40 bytes(320-bits) "Pseudo header(의사 헤더)" + "TCP Header" + "Payload Data"에 대한 checksum을 계산한 값입니다.
- Pseudo header format (IPv6 인 경우, 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
- Pseudo header format (IPv6 인 경우, RFC2460 Section-8.1)
- IPv4의 경우 12 bytes(96-bits) "Pseudo header(의사 헤더)" + "TCP Header" + "Payload Data"에 대한 checksum을 계산한 값입니다.
- 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)된 경우, 이 값은 유효하지 않습니다.
- URG flag가 설정(1)된 경우, 순번으로부터의 위치(Offset)을 나타냅니다. 이 위치(Offset)가 마지막 긴급 데이터 바이트를 가리키게 됩니다.
- 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
- AES:15 bytes
- DES:7 bytes
- 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)
- Size of Initialazation Vector for
- 확실한 이해를 위해서는 Linux kernel의 esp4_get_mtu() 함수를 반드시 이해하면 도움이 됩니다. (주어진 실제 MTU로부터 ESP Overhead를 계산해서 MTU에 반영해주는 함수) Data는 가변이기 때문에 결국 최대 가능한 padding 크기일때를 기준으로 MSS를 계산해야 합니다.
- IPSecVPN에서 AES-256 with SHA-1 기준)을 기준으로 ESP Header+Trailer size는 73 bytes 이며 IPv4에서 MTU 1500인 경우 최대 MSS크기는 1387 octets가 됩니다. 하지만 실제 최대 MSS크기는 1388 octets가 가능합니다.
- 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)
- TCPOLEN_MD5SIG: 18 bytes
- 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
- 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)
- TCPOPT_EOL(0): End of options
- LEN: TYPE + LEN + OPTDATA를 합한 크기 (참고: https://www.freesoft.org/CIE/Course/Section4/8.htm)
- TYPE이 TCPOPT_NOP과 TCPOPT_EOL인 경우는 예외적으로 LEN과 OPTDATA가 없으며 그 외의 TYPE은 모두 적어도 LEN은 2 이상의 값이어야 하며 LEN이 2인 경우는 OPTDATA가 없음을 의미합니다.
- TYPE
- Data offset의 값이 5인 경우는 Options와 Padding이 없음을 의미합니다.
- Options + Padding 의 크기(bytes)는 (Data offset - 5) * 4 으로 계산할 수 있습니다.
- 하나의 Option은 "TYPE(1bytes) + LEN(1bytes) + OPTDATA(n)" 와 같은 형태로 여러개의 Option을 추가할 수 있습니다. (Options의 총 크기는 최대 40 bytes 를 넘을 수 없으며 32bits 로 정렬되기 위해서 padding을 포함할 수 있습니다.)
- Padding: variable
- TCP Header의 마지막 부분은 32bit로 정렬되어야 하기 위함. (Options의 마지막이 32bit로 정렬하기 위함)
- Padding에 채워지는 값은 0입니다.
1.2. TCP 상태 천이도 (TCP state diagram)
참고 이미지 |
[PNG image (69.29 KB)] |
이미지 출처: 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
- SYN : TCP Client 는 TCP Server 로 SYN 을 전송.
- 초기 순번(ISN: Initial Sequence Number) A 는 임의의 초기 값으로 결정하여 전송
- SYN + ACK : TCP Server는 TCP Client 로 SYN + ACK 으로 응답.
- 이 때 Acknowledgment Number는 TCP Client로부터 받은 초기 순번(ISN: Initial Sequence Number)에 1을 더한 A + 1 값으로 응답
- Sequence Number는 임의의 다른 값 B로 결정하여 응답
- 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를 함께 전송하기도 함.
- SYN : TCP Client 는 TCP Server 로 SYN 을 전송.
1.4. TCP 연결 종료
- four-way handshake : 연결 종료는 각자 FIN을 전송하고 그에 대한 응답 ACK를 받는 흐름)
- FIN : 연결 종료을 시작하는 쪽에서 FIN을 전송
- ACK : FIN을 받은 쪽에서 ACK응답
- FIN : 연결 종료를 받은 쪽에서 FIN을 전송
- ACK : 연결 종료를 시작한 쪽에서 최종 ACK를 전송
- three-way (or 3-step) handshake
- FIN : 연결 종료을 시작하는 쪽에서 FIN을 전송
- ACK+FIN : FIN을 받은 쪽에서 ACK + FIN 응답
- ACK : 연결 종료를 시작한 쪽에서 최종 ACK를 전송
- half-duplex close sequence
- FIN 대신에 RST를 전송하여 연결을 종료
- 더이상 아무것도 전송하는 것 없이 종료 처리되어야 함.
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. 참고자료
- OSI 7 계층모델
- IPv4
- IPv6
- Computing the Internet Checksum (RFC1071)
- 이더넷 (Ethernet)
- ICMP(Internet Control Message Protocol)
- NAT(Network Address Translation)
- VPN(Virtual Private Network, 가상사설망)
- 각종 TCP/IP 프로토콜 스택들
- RFC793 - TRANSMISSION CONTROL PROTOCOL DARPA INTERNET PROGRAM PROTOCOL SPECIFICATION
- RFC1071 - Computing the Internet Checksum
- RFC1122 - Requirements for Internet Hosts -- Communication Layers
- RFC1323 - TCP Extensions for High Performance
- RFC1379 - Extending TCP for Transactions -- Concepts
- RFC1948 - Defending Against Sequence Number Attacks
- RFC2018 - TCP Selective Acknowledgment Options
- RFC2460 - Internet Protocol, Version 6 (IPv6) Specification
- RFC3168 - The Addition of Explicit Congestion Notification (ECN) to IP
- RFC3540 - Robust Explicit Congestion Notification (ECN) Signaling with Nonces
- RFC5681 - TCP Congestion Control
- RFC6247 - Moving the Undeployed TCP Extensions RFC 1072, RFC 1106, RFC 1110, RFC 1145, RFC 1146, RFC 1379, RFC 1644, and RFC 1693 to Historic Status
- RFC6298 - Computing TCP's Retransmission Timer
- RFC6824 - TCP Extensions for Multipath Operation with Multiple Addresses
- RFC7323 - TCP Extensions for High Performance
- RFC7414 - A Roadmap for Transmission Control Protocol (TCP) Specification Documents
- https://en.wikipedia.org/wiki/Transmission_Control_Protocol
- https://en.wikipedia.org/wiki/Protocol_data_unit
- https://hpbn.co/building-blocks-of-tcp/
- Three-Way Handshake
- SYN
- Client picks a random sequence number x and sends a SYN packet, which may also include additional TCP flags and options.
- SYN ACK
- Server increments x by one, picks own random sequence number y, appends its own set of flags and options, and dispatches the response.
- ACK
- Client increments both x and y by one and completes the handshake by dispatching the last ACK packet in the handshake.
- SYN
- Three-Way Handshake
- Service Name and Transport Protocol Port Number Registry
- https://live.paloaltonetworks.com/t5/Learning-Articles/TCP-MSS-adjustment-for-IPSec-traffic/ta-p/74988
- http://www.freesoft.org/CIE/Course/Section4/8.htm
- https://www.joinc.co.kr/w/Site/TCP_IP/TCP_Header
- https://kldp.org/node/30779
- https://live.paloaltonetworks.com/t5/Learning-Articles/TCP-MSS-adjustment-for-IPSec-traffic/ta-p/74988
- https://cs.senecac.on.ca/~raymond.chan/topics/tcp/checksum.html
- https://sostarzia.tistory.com/44?category=222287
- http://www.ktword.co.kr/test/view/view.php?m_temp1=1889
- https://rhyshan.com/278
- https://mr-zero.tistory.com/36
- https://brunch.co.kr/@lars/1
- O'REILLY사의 "Understanding LINUX NETWORK INTERNALS" 서적
- https://m.blog.naver.com/s2kiess/30165976105 (TCP Response)
- https://12bme.tistory.com/538
- https://meetup.toast.com/posts/55
- https://serverfault.com/questions/866234/rst-ack-after-syn-and-retransmission
- https://tech.kakao.com/2016/04/21/closewait-timewait/
- https://m.blog.naver.com/newyks/220268492408 ("TCP 세그먼트의 Sequence number?")
- 리눅스 서버의 TCP 네트워크 성능을 결정짓는 커널 파라미터 이야기 - 3편
- https://m.blog.naver.com/goduck2/221117234954