1. TCP 2. TCP Segment 2.1. Segment 구조 3. TCP 연결 : 3-way-handshaking 4. 오류 제어 Error Control 4.1. checksum 4.2. 재전송 시나리오 4.1. TCP의 RTT 설정 방법 5. 흐름 제어 Flow Control 6. 혼잡 제어 Congestion Control 6.1. 혼잡 제어와 흐름 제어의 차이 6.2. CWND 6.3. 혼잡 제어의 동작
TCP
Transport Layer에 위치하고 있는 프로토콜입니다.
크게 다음과 같은 기능을 제공하고 있습니다.
전이중 서비스
흐름 제어
오류 제어
혼잡 제어
연결 지향 서비스
신뢰성 서비스
세그먼트
TCP의 신뢰성 있는 전송을 위한 5가지 기법입니다.
Checksum 검사합
Ack, nAck 확인 응답
pipeline 동시에 여러개
seq. num 순서 번호
timer 타이머
Segment
TCP는 기본적으로 Process으로부터 내려오는 데이터를 각각 Buffer에다가 보관합니다.
이후 buffer에 있는 데이터 일부를 조합하여 Segment라는 Data Packet으로 만든 후에
IP 계층에 전달합니다.
이후 이 Segment들에게 각각의 순서 번호 1, 2, 3... 를 할당합니다.
TCP의 Segment 구조
Process로부터 발생된 데이터를 조합하여 만든 TCP만의 Packet 형식
Data 구조
Buffer로부터 가져온 데이터들로 구성되어 있습니다. 이들 바이트 데이터들은 각각의 번호를 가지고 있으며, 첫번째 바이트에 부여된 번호를 해당 Segment의 Sequence Number(순서 번호)로 지정합니다.
20~60 Bytes의 Header를 가지고 있습니다.
Header 구조
Source Port Address, Destination Port Address : 발신지와 도착지의 Process Port 번호 Sequence number(순서 번호) : segment에 포함된 데이터의 첫번째 바이트에 부여된 번호 Acknowledgement number(확인 응답 번호) : 잘 수신받았다고 응답, 수신받은 바이트 데이터 그 다음 번호를 보냄 Header Length(헤더 길이) : TCP 헤더 길이, 4Bytes의 Words 값으로 표현 Control : 제어 또는 flag receive window : Server나 Client 자신이 받을 수 있는 최대 window 사이즈 checksum : 오류합으로 해당 segment가 제대로 되었는지 확인 Urg data pointer :
1. client는 Connection을 보내도 되냐는 SYN Packet을 보냅니다. 이때 SequenceNum은 x라 가정합니다. 2. Server측에서는 "연결해도 좋다"라는 OK 사인의 ACK Packet과 함께 Server측에서도 Client와의 연결을 위해 SYN Packet을 보냅니다. 이때 AckNum은 x+1로 SequenceNum은 새로운 숫자인 y로 설정됩니다. 3. Client측은 "연결해도 좋다"라는 OK 사인을 Server에게 보냅니다. 이때 AckNum은 y+1 입니다.
연결 종료 Closing a connection
연결을 종료하기 위해서 다음과 같은 단계를 거쳐야 합니다.
이때, Client, Server 각각의 상태들을 알고 있어야 합니다.
1. flag를 FIN으로 하고 Seq가 x인 패킷을 보냅니다. 지금까지 Client는 데이터를 보낼 수 없는 상태가 됩니다. 2. Server는 "Client는 연결 종료해도 좋다"는 메세지를 전달하기 위해 flag가 ACK이며 AckNUM이 x+1인 것을 보냅니다. 3. Client는 이제 서버가 close할 때까지 기다립니다. 4. Server 측에서 FIN, SeqNumy를 보냅니다. 이때부터 Server도 데이터를 보낼 수 없게 됩니다. 받을 순 있습니다. 5. Client는 "Server도 연결 종료해도 좋아"라는 메세지를 전달하기 위해 ACK, AckNumy+1을 보냅니다. 이때 Client는 서버가 종료되는 시점을 모르기 때문에 timed wait으로 대체합니다. 6. max segment lifetime의 2배정도를 기다린 후에 Client도 연결을 종료합니다.
부록 : Sender, Destination과 Client, Server는 어떤 차이?
Sender와 Destination은 종단과 종단의 느낌이였다면
Client, Server는 방향성 까지 고려하기 때문에
Client가 Sender과 될 수 있고 Destination도 될 수 있습니다.
TCP에서는 Client, Server로 표현하는 것이 맞는 표현방식입니다.
부록 : TCP의 MTU는?
TCP는 Segment라는 단위를 사용하므로
MSS(Maximum Segment Size)라는 단어를 사용합니다.
MSS : 1420~1460Bytes
부록 : RDT, TCP ??
TCP는 기본적으로 RDT protocol에 기반한 protocol입니다.
RDT는 Sender Receiver에만 초점을 두었다면
TCP는 RDT를 양방향으로 사용하고 있다고 보면 될 것 같습니다.
오류 제어 Error Control
이제 TCP를 통해 1대1 연결을 하면 해당 파이프라인으로 데이터를 보냅니다.
그러나, 데이터를 보내는 과정에서 중간에 통신상태가 원활하지 않아
패킷이 훼손되거나 손실되었다면 어떻게 해야할까요?
TCP의 오류 발견 도구
checksum 검사합
Ack, Nack 확인응답
Timeout 시간 초과
TCP의 오류 복구(제어) 기법
Segment를 재전송하는 기법에 기초합니다.
checksum
데이터가 온전하게 잘 전달되었는지 무결성을 확인하는 기법입니다.
이를 통해 데이터가 훼손되었는지 확인이 가능하며 만일 checksum을 통해 훼손되었음이 검출되었다면
재전송을 요청합니다.
재전송 시나리오 Retransmission scenarios
Cumulative ACK은 말 그대로 번호가 축적되는 것을 의미합니다.
그래서 Server에서 100, 120, 140까지 받을 때 중간에 loss되어도
오류 재전송 이후 141부터 보내라고 할 수 있습니다.
Duplicate ACK은 번호가 반복되는 것을 의미합니다.
중간에 loss가 일어나도 pipeline으로 인해 Client가 계속 데이터를 보낼 때
중간에 에러난 ACK 번호를 계속 반복해서 보냅니다.
ACK이 delay되어서 sender에게 들어왔을 때 시나리오 - Cumulative ACK
Host A 입장에서는 RTT까지 기다렸지만 ACK이 오지 않아서 다시 Seq92부터 Segment를 보냈습니다. Host B 입장에서는 이미 바이트 스트림 119까지 받아서 다음에 오는 Seq92 Segment는 duplicate이기 때문에 제거하고 Host A에게 119까지 받아서 120을 보내달라는 ACK120을 보냅니다.
ACK이 중간에 loss 당했을 때 - Cumulative ACK
Host A 입장에서는 온전히 다 보냈지만 ACK이 중간에 깨져도 마지막 ACK이 120일 경우 Host A는 100을 보내지 않고 119까지 잘 받았으므로 ACK 120을 보냅니다.
Seq이 중간에 loss당해서 전달이 안됬을 때 시나리오 - Duplicate ACK
Host A는 pipeline 방식으로 한꺼번에 보내는데 중간에 Seq100 세그먼트가 loss되었습니다. Host B 입장에서는 다음 ACK인 100이 안들어왔기 때문에 계속해서 ACK100을 보냅니다. Host A 입장에서 만약 3번 이상 같은 ACK이 반복해서 온다면 timeout되기 전에 Seq100을 보내게 됩니다.
RTT만큼 기다리지 않고 바로 세그먼트를 다시 보냈습니다. 이를 TCP fest retransmit이라고 합니다.
흐름 제어 Flow Control
송신자의 TCP socket buffer가 overflow가 되지 않도록 해야합니다.
window 조절
RDT 프로토콜에 있는 Go-Back-N에서의 window 조절 방식을 이용합니다. 이미 Client로부터 온 데이터를 제외한 나머지 공간을 rwnd(receive window)라고 표현하며 이는 TCP 3-way-handshake 연결할 때 미리 Client에게 '내가 처리할 수 있는 버퍼 크기'를 알려줍니다.
흐름을 통제하는 여러 기법들이 존재합니다.
Stop-and-wait
Go-Back-N (Sliding Window)
Selective Repeat
이들은 RDT 포스팅에서 자세히 다루었으니 이를 참고해주세요
혼잡 제어 Congestion Control
라우터에서 여러 방면으로 데이터가 들어오게 될텐데
각 traffic 마다 들어오는 속도 차이가 다를 것입니다.
한순간에 엄청나게 들어올 수 있기 때문에 언제 혼잡이 발생할지 모릅니다.
이를 위해 TCP에서는 혼잡 제어 알고리즘들을 사용하여 제어합니다.
혼잡 제어와 흐름 제어의 차이
흐름제어가 송신측과 수신측 사이의 전송속도를 다루는데 반해
혼잡제어는 호스트와 라우터를 포함한 보다 넓은 관점에서 전송 문제를 다룹니다.
혼잡 윈도우 Congestion Window CWND
RWND (Receive Window) : 수신자 윈도우 크기, flow control에서 나온 개념
CWND (Congestion Window) : 송신자 자신이 네트워크의 상황을 고려해서 정한 혼잡 윈도우 크기
이들 중에서 더 작은 값을 최종 window 크기로 정합니다.
혼잡 윈도우 처음 설정할 때
처음에는 혼잡 윈도우의 크기를 1 MSS로 정합니다. 1 MSS는 1460Bytes 이므로 1 CWND = 1 MSS = 1460 Bytes
이후 네트워크의 혼잡 상황을 유추하여 CWND의 크기를 조절합니다.
혼잡 제어의 동작
혼잡 제어를 위한 알고리즘들입니다.
slow start Algorithm 느린 출발 알고리즘
congestion avoidance Algorithm 혼잡회피 알고리즘
congestion detection algorithm 지수 감소 알고리즘
혼잡 회피 단계
1. Slow Start(느린 시작) : threshold(임계점)(window크기 반)(최초 임계점은 65535)를 설정하고 2^n 지수증가, 임계치에 도달할 때 까지 확인 응답이 오면 가산 증가 2. Congestion Avoidance(가산 증가) : 임계치에 도달하면 CWND 1씩 증가 3. Congestion Detection(지수 감소) : 혼잡 발생 시 임계치를 현재 윈도우 크기의 반으로 줄여서 다시 CWND 1로 느린시작
혼잡 상태라는 것을 2가지를 보고 알 수 있습니다.
Timeout
3-duplicated-ACKs
2가지의 혼잡 상태 검출에 따라 Congestion Detection 방식이 다릅니다.
시나리오들을 보면서 살펴보겠습니다.
혼잡 제어의 다양한 시나리오들
Timeout
위의 혼잡 회피 단계와 동일합니다. Time-out이 발생했을 경우에 지수 감소 단계에 돌입하게 되고 CWND를 1까지 뚝 떨어뜨리게 됩니다.
3-duplicated-ACKs
3-duplicated-ACKs이 발생한 지점에서는 Timeout과는 다르게 threshold부터 시작하게 됩니다. 그래서 지수승으로 증가하는 것이 아닌, 가산 증가를 하게 됩니다.
TCP Taheo, Reno
Taheo는 1세대 TCP 버전으로써
혼잡 제어가 발생하면 무조껀 cwnd가 1로 초기화 됩니다.
Reno는 2세대 TCP 버전으로써
위에처럼 3-Duplicated-ACKs이 발생하면 cwnd가 임계점부터 시작하게 됩니다.