Study/Network

[Network] TCP/IP

__PS 2024. 4. 19. 22:05
728x90

TCP: 연결 지향

Stream Delivery

TCP: byte stream

UDP: bound delivery


Sequence Number

- TCP 세그먼트의 연속된 번호

- random

 

ACK

1. Selective ACK

-> 받은 데이터의 시작 번호를 반환

 

2. Cumulative ACK

-> 받은 데이터의 다음 번호를 반환


TCP segment format

- Header: 20 ~ 60 bytes

 

16 bit: src port address

16 bit: dst port address

32 bit: sequence number

32 bit: acknowledge number

4 bit: HLEN

6 bit: reserved

6 bit: Flag

16 bit: window size

16 bit: checksum

16 bit: urgent point

options

 

주요 Flag

1. ACK 

2: SYN

3. FIN 

 

Chekcsum

- TCP에서는 필수 요소

- IP header에 존재하는 16 bit TCP total length도 포함하여 진행

-> 해당 pseudoheader를 보내지는 않음


Three way handshake

1. Establish

client: SYN 전송 /  random seq 포함하여 전송

server: SYN + ACK 전송 / random seq, 이전에 받은 seq + 1의 ack, rwnd 포함하여 전송

client: ACK 전송 / 이전에 받은 seq + 1의 ack, rwnd 전송

 

- SYN, ACK은 데이터를 포함하지 않음

- UDP는 이런 셋업 과정 X 

 

2. Terminate

client: SYN + FIN 전송

server: FIN + ACK 전송

client: ACK 전송

 

만약 server의 응답 중

FIN, ACK 응답의 시간이 길면 4 way handshake라고도 보는 경우가 있음

 

Half Close

- server가 보낸 데이터를 송신 가능, 수신 불가


Timeline diagram

client가 SYN을 보낸 상황 = SYN-SENT, server = LISTEN

server가 SYN + ACK을 보낸 상황 = SYN_RCVD

client가 ACK을 보낸 상황 = ESTABLISHED

...

client가 FIN을 보낸 상황 = FIN-WAIT1

server가 ACK을 보낸 상황 = CLOSE-WAIT

server가 FIN을 보낸 상황 = LAST-ACK, 그 전까지 client = FIN-WAIT2

client가 ACK을 보낸 상황 = TIME-WAIT

=> 2MSL로 1 ~ 2분을 기다림.

=> server가 ACK을 받지 못한 경우 FIN을 다시 보낼 것이므로 기다리기 위한 시간

 

Fin이 전송되는 경우

1. close() 함수 호출

2. 프로세스가 종료될 때

3. ctrl + c로 강제 종료

-> server가 time-wait 상태로 감

 

TCP 서버의 함수 호출 순서

1. socket() -> 소켓 생성

2. bind() -> 소켓 주소할당

3. listen() -> 연결 요청 대기 상태

4. accept() -> 연결 허용

5. read() / write() -> 데이터 송수신

6. close() -> 연결 종료 => FIN이 전송


FLOW CONTROL (흐름 제어)

첫 번째 ACK이 오기까지 얼만큼의 데이터를 보낼 수 있을

-> 상대방이 받을 수 있을만큼

-> 시시각각 변함

 

Window size = min (rwnd, cwnd)

ack 기준 다음 버퍼부터 전송

-> 속도는 TCP가 조절

 

Silly Window Syndrome

헤더 크기에 비해 보낼 데이터가 비효율적으로 적은 경우

 

1. 송신 

Nagle algorithm

1) 보낼 데이터가 MSS만큼 쌓이면 전

2) MSS보다 작을 경우 ACK이 오면 전

 

default = ON

delay가 민감하면 Nagle OFF, 아니라면 ON

 

2. 수신

1) Clark: MSS만큼의 빈 공간이 생길 때 까지 | buffer 공간의 절반이 남았을 때까지 rwnd = 0으로 전송

2) ACK 전송 지연

 

SYN Flooding

client가 임의의 주소로 server에 SYN을 보냄

-> server는 연결 요청 대기 큐에 넣음

-> SYN + ACK을 계속 client에 보내나 돌아오는 ACK이 없음

-> 계속해서 기다리므로 지연 발생

-> DOS (SYN Flooding)

=> Distributed Denied of Services == DDoS

 

사용자가 본인의 주소를 가짜 주소로 바꾸어 서버에게 대량의 SYN을 보내면

서버는 SYN + ACK을 보내고 연결요청 대기 큐에 넣음

-> 돌아오는 ACK이 없으므로 정상적인 연결이 안됨

=> SYN Flooding


ERROR CONTROL

TCP는 신뢰성을 보장

 

Rule 1

: sending buffer를 봐서 보낼 데이터가 있다면 헤더에 ACK을 실어서 보내자

Rule 2

: buffer를 봤는데 보낼 데이터가 없다면 50ms를 기다리고 ACK을 보냄

Rule 3

: 들어온 데이터가 2개라면 ACK을 하나 보냄

-> 두 당 하나

 

Rule 4

: Out of order (응급 상황)이므로 ACK을 바로 보냄

Rule 5

: 빈 공간이 채워지면 다시 다음 ACK을 보냄

패킷 로스 확인: 패킷마다 timer를 켜고, timer가 지나도 ACK이 없으면  

fast retransmission

: 세 개의 중복된 ACK이 도착하면 time out까지 가는 것이 아니라 바로 패킷 로스로 간주

-> 빠르게 재전송함

-> fast인 이유: time out까지 도달하지 않음
-> RTO를 길게 잡아야 함

 

cumulative 방식: 패킷 로스의 여부를 확인할 수 없음

로스 된 이후의 패킷을 한 번에 다 보냄

ex) 301 ~ 801이 전송 되었으나 301이 안보내졌고, 

ACK 301이 3번 전송되면 fast restransmission에 의해

301 ~ 801을 다시 전송

Rule 6

: 받은 패킷이 오면 그 이후 받고 싶은 ACK을 다시 보냄

 

deadlock

server -> client로 최종 ACK을 보냈으나, 이것이 누락된 경우 하염없이 기다림

 

Persistent Timer

교착 상태를 해결하기 위해 사용

-> 영속 타이머가 만료되면 probe 세그먼트 전송

 


CONGESTION CONTROL

 

TCP1 100Mbps, TCP2 100Mbps -> 총 200Mbps를 전송

라우터에서는 100Mbps만 감당 가능

-> 혼잡한 상황

 

cwnd: sender가 관리

 

additive increase, congestion avoidance

-> 혼잡 구간이 아닌 곳에서 혼잡 발생을 방지

중앙 통제가 없으므로 얼만큼 보내야하는지 잘 모름

-> 보내는 양을 조금씩 늘려감

-> 어느 순간 혼잡이 발생-> 보내는 양을 절반으로 줄임

 

slow start, exponential increase

만약 100차선처럼 많으면

천천히 100까지 늘려가야하므로 오래걸림

-> 두 배씩 늘리자

=> slow start, exponential increase

flow control과 비교했을 때 느리므로 

threshold까지 도달하면 두 배씩 증가를 중단, packetloss가 발생해도 증가 중단

 

 

처음 연결 -> slow start -> 두 배씩 증가시키다가

threshold를 만나면 stop

이후 consgestion avoidance에서 additive increase 진행

혼잡이 발생하면 cwnd를 반으로 줄여 다시 additive increase를 진행

 

packetloss -> 혼잡으로 받아들이는 이유

-> 혼잡에 의해 packet을 버리는 경우가 많음

 

RTT vs RTO

RTT: Round Trip Time

-> 패킷의 응답까지 걸리는 시간

 

RTO: Retrun Time Out

-> 데이터 전송 후 재전송을 위해 걸리는 시간

 

AIMD

Additive Increase Multiplicative Decrease

 

time out이 발생하면

window size를 1부터 시작

 

slow start를 진행

-> threshold가 필요

timeout이 발생했을 당시의 window size의 절반을 새로운 threshold로 사용

 

두 배씩 커지다 threshold에서 stop

 

slow start가 없었을 때 flow control로 관리

과거에는 2^16인 65000바이트를 한 번에 쏟아냄


TCP Fair

계속해서 혼잡이 발생한다면 두 연결은 절반으로 줄어드므로 결국 throughput은 50 : 50이 될 것이다.

만약 두 연결의 RTT가 다르다면 기울기가 달라질 것이다.


Timers

Retransmission

retransmission timer에 의해 packet loss를 detect하면 slow start로 들어감

 

1) persistence timer

- rwnd를 0으로 받은 경우 timer를 켜서 probe segment를 전송

- rwnd와 ack이 넘어옴

deadlock 상황: rwnd !=0 인 패킷이 전송되지 않은 경우

 

2) keepalive timer

- 오랜 기간 idle 상태에 있는 것 방지

- 서버가 2시간 동안 클라이언트로부터 세그먼트를 전송받지 못했다면, probe segment를 전송

 

Smoothed RTT

첫 번째 측정 이후 RTTs = RTTm

그 이후 RTTs = 7/8 * RTTs + 1/8RTTm

 

RTT Driven 

첫 번째 측정 이후 RTTd = RTTm / 2

그 이후 RTTd = 3/4RTTd + 1/4|RTTs - RTTm|

 

RTO

RTO = RTTs + 4 * RTTd

초기 RTO = system에서 설정한 값

 

ex)

SYN을 보내고 SYN + ACK이 오기까지 1.5가 걸린 경우

- RTTm = 1.5

- RTTs = RTTm = 1.5

- RTTd = RTTm / 2 = 0.75

-> RTO = RTTs + 4 * RTTd = 4.5

 

이후 데이터를 전송하고 ACK이 오기까지 2.5가 걸린 경

- RTTm = 2.5

- RTTs = 7/8RTTs + 1/8RTTm = 1.625

- RTTd = 3/4RTTd + 1/4|RTTs - RTTm| = 0.78

-> RTO = RTTs + 4 * RTTd = 4.74

 

Karn's Algorithm

재전송 되는 경우 응답이 RTO 이후에 도착하는 경우도 존재

-> RTT 계산 X

-> 정상적인 패킷 전송 이후 다시 계산 시작

-> 재전송시 RTO = RTTs + 4 * RTTd가 아닌 2 * RTO로 계산


OPTIONS

- single byte

- multiple byte

 

1) 3-byte option

- EOP (End Of Option): 한 번만 사용 가능 / 맨 뒤에 존재

- NOP (No Operaton Option): 여러번 사용 가능 / 앞에 존재

 

2) Maximum Segment Size (4 byte)

- sender, reciever가 상의하여 조절 가능

- setup 과정에서 합의해야 함

- 중간에 변경 불가능

 

3) scale - factor (3 byte)

- setup 과정에서 약속

 

ex) RTT = 1초의 throughput

rwnd = 1111...11인 경우 최대 2^16 byte

2^16 byte = 2^10 * 2^6 byte = 64KByte

64KByte / s = 64 * 8bits / s = 512Kbps = 0.5Mbps

 

ex) RTT = 100ms

64KByte / 0.1s = 5Mbps

 

-> 사이즈를 2^n만큼 키우고 싶음 -> scale factor에 n 저장

if) rwnd = k라고 왔다면, k * 2^n으로 인지

 

4)  time stamp option

- RTT 측정시 사용

-> option에 출발 시간을 적어 보낸 것을 바탕으로 상대방이 ACK을 보낼 때 출발 시간을 적어서 보냄

-> RTT를 계산

 

- PAWS (Protection Against Wrapped Sequence number)

-> sequence number가 random이지만, 일치할 가능성 존재

-> time stamp를 통해 언제 전송된 패킷인지 구분

 

5) SACK

- setup 과정에서 약속

- 중간에 loss된 경우 해당 패킷 이후 모두 전송이 비효율적

- cumulative의 단점인 이후의 상황 보완

- 블럭을 생성

- 받은 시작 주소 ~ 마지막 주소 + 1을 저장

- 첫 번째 블록에는 중복된 내용을 기입할 수도 있음