TCP connection setup
TCP는 connection oriented protocol이다. 일단 한번 관계를 맺으면 통신을 할 수 있다.
- TCP is bi-directional : 하나의 connection을 가지고 양방향에서 데이터를 주고 받을 수 있다.
- Each side should initialize connection : 처음에는 연결을 먼저 시도한다
- connection setup: 3-way handshake
- the client sends SYN to the server : connection을 맺기 위해서 SYN을 보낸다.
- the server sends SYN+ACK to the client : 자신도 연결을 맺기 위한 SYN을 함께 보낸다.
- the client sends ACK to the server : 받은 것에 대해서 ACK를 다시 보낸준다. 데이터가 포함될 수 있다.
- 3-way handshake
connection 을 맺을때 서로간에 syn을 맞추어야하는 정보가 있다. 그게바로 seq num이다.
그림에서는 처음 8000으로 보낸다. seq num의 시작점은 8000으로 설정하겠다는 의미이다. 이때의 숫자는 랜덤으로 32bit안에서 나올 수 있는 숫자이다.
server은 랜덤 번호 15000을 client쪽으로 보낸다. 그리고 ACK는 seq num + 1으로 설정해 놓는다.
마지막 ACK는 seq num이 8001이 되고 ack도 받은 숫자+1을 해서 보내준다.
- a SYN packet does not carry data, but it consumes one byte number : 처음 SYN은 데이터가 없고 한 byte 숫자를 사용한다.(8001에서 시작한다)
- If the sequence number of SYN packet is 8000, the
server acknowledges with acknowledgement number 8001
- ACK packets do not consume byte numbers : seq는 8001에서 시작한다.
(요약)
TCP는 연결시 3-way handshake를 한다.
snd SYNbit=1 인것을 보낸다. seq는 랜덤하다
rcv SYN, ACK을 1로 설정하여 보낸다. seq는 랜덤이고 ack는 seq+1이다.
snd ACK를 1로 설정하여 보낸다. seq는 ack로하고 ack는 seq+1로 보낸다.
끊을때는
snd FINbit=1로 해서 보내고
rcv ACKbit=1로 보내고
rcv FINbit=1로 해서 보내고
snd ACKbit=1로 보내고
Detour: SYN flooding attack
- one of DoS (Denial-of-Service) attacks : 해커들이 한 기관에 무수히 많은 요청을 보내서 다른 사용자가 사용하지 못하게 하는 것
- use false source IP addresses to pretend multiple
clients are sending SYN packets to the server : 여러명의 client가 server로 SYN 패킷을 보내는 것처럼 한다.
- users cannot connect to the server : 사용자는 서버에 접속하지 못한다.
- what makes SYN flood attack feasible : SYN이 왜 공격에 유용한가?
- when the server receives SYN, it sends SYN+ACK and waits for ACK (half-open) : ACK를 서버에서 기다리는데 이를 half-open상태라고 이야기 한다.
- The server needs to save the client record in the half - open state, which uses up memory : 서버가 ACK가 오는 것을 기다리면서 client에 대한 정보를 가지고 있어야 한다. 그래서 server은 client record를 가지고 있어야 한다. 이를 위해 일부 메모리를 서버에서 사용하게 된다.
TCP connection teardown
연결을 종료하는 방법으로 3-way handshake를 사용한다.
client에서 보낸때 FIN을 키고 server도 FIN을 켜서 패킷을 보낸다.
half-close
- A state where connection on one direction is closed : 한쪽 방향만 닫히고 다른쪽 방향은 아직 열려 있는 상황
- The other direction is still open
- The client sends FIN to the server : client가 FIN을 보낸 상황
- The server sends an ACK (instead of FIN+ACK) : server는 아직 데이터를 보내는 중이라서 ACK만 보낸다.
- In this state, only server can send data to the client : 오직 server만 client쪽으로 데이터를 보낸다.
server은 계속 데이터를 보내다가 마지막에 FIN을 보내서 완전히 connection이 종료된다.
TCP sliding window
-
Bytes are transferred using send window and receive
window : 한 host에서 receive와 sender window두개 다 있어서 두개의 역활 모두 될 수 있다.
-
variables regarding send window : send window에서 중요한 변수들
- LastByteAcked: sent the byte, received ACK : window가 시작하기 바로전 바이트
- LastByteSent: sent the byte : 마지막으로 보낸 byte중에서 마지막 byte
- LastByteWritten: application sent the byte to the TCP : 윈도우 바깥에 있는 byte
- LastByteAcked ≤ LastByteSent ≤ LastByteWritten
-
variables regarding receive window
- LastByteRead: application read the byte from TCP
- NextByteExpected: byte must be received from the sender : 다음번 받을 byte
- LastByteRcvd: last byte received (disregarding missed bytes) : 마지막 받은 byte위치
- LastByteRead < NextByteExpected ≤ LastByteRecv + 1
-
Send window range
- LastByteAcked to LastByteSent
- When an ACK arrives, the window slides to the right : ACK를 받았다면 window slide가 오른쪽으로 이동하게 된다.
- Send window size is decided by flow control and congestion control : send window size는 flow control과 congestion control에 의해서 결정이 된다.
-
The sender sends bytes in the sliding window
-
bytes outside the window cannot be sent
window size는 receive window 와 congestion window중 더 작은 값으로 결정이 된다.
-
Left of the sliding window: bytes sent and acknowledged
-
Inside the sliding window: bytes that can be sent
-
Right of the sliding window: bytes that cannot be sent
-
liding window size: min(rwnd, cwnd)
-
cwnd (congestion window): depends on network status : 네트워크 코어에 있는 라우터들의 상태에 의해 만들어지는 윈도우의 사이즈
-
rwnd (receiver window): depends on receiver status : receiver가 어떤 상태인가에 의해서 결정되는 값이다.
- advertised window
윈도우 안의 byte들은 이만큼 보낼 수 있다.
TCP sliding window: example
- The receiver host B has a buffer with size 5,000 bytes
- The buffer currently holds 1,000 bytes of unprocessed data
- What is the B’s advertised window (rwnd)?
- 5000 – 1000 = 4000
남은 공간이 4000byte인데 이걸 sender쪽으로 알려줘야 한다. 이것을 advertised window라고 한다.
- If rwnd is 3,000 bytes, and cwnd is 3,500 bytes : rwnd 가 3000이고 cwnd가 3500인 경우
- What is the resulting window size? : send window size는 3000byte가 된다.
=== Sliding Window Control ===
1. Sliding Window Size
-
The sending speed depends on the sliding window
size : sliding window size는 데이터를 얼마나 빠르게 보낼 수 있는가를 결정하게된다.
-
Large sliding window -> sender sends bytes rapidly
-
Small sliding window -> sender sends bytes slowly
-
Why not just have a large sliding window then?
-
If sending speed is too fast
- Packets may be dropped at the routers : 라우터가 패킷을 버릴수 있다.
- Packets may be dropped at the receiver : receiver에서 처리하는 것보다 더 많이 오면 receiver에서 패킷을 버릴 수 있다.
- Packet drop -> Retransmission -> Waste of bandwidth : 재전송을 하게되면 대역폭의 낭비를 부추긴다.
-
If sending speed is too slow : 너무 느린경우
- Waste of bandwidth : 대역폭을 낭비한다.
-
WHAT IS THE PROPER SIZE?
-
Send as much as possible, but…
-
Packets should not be dropped at the receiver : receiver가 받을 수 있도록 속도를 적절히 조절해 주는 것을 FLOW CONTROL이라고 부른다.
-
Packets should not be dropped at the routers : 라우터에서 패킷드랍이 발생할 수 있다. 그래서 라우터에서 drop되지 않도록 하는 것
Flow Control
데이터가 오면 버퍼에 저장이 되어 있다가 processing되는데로 application으로 가져간다. 그래서 시간을 조금 두는 것이다.
빨간부분을 보면 16bit가 할당이 되어 있다. sender가 패킷을 받으면 window size를 보고 RWND와 비교하여 window size를 결정하게 된다.
- Receiver tells sender how much space is left in its
receive buffer : receiver가 sender에게 공간이 얼마나 남았는지 알려주게 된다.
- ‘Window Size’ field in the TCP header
- The sender records it as RWND (Receive Window)
(요약)
flow control은 컴퓨터가 매우 느려서 패킷을 읽는 속도가 매우 느릴 수 있다.
그래서 데이터를 받을때는 buffered data와 아직 남은 free buffer space(rwnd)가 존재한다. 이걸 보고 sliding window(RcvBuffer)라고 부르게 된다.
receive buffer의 사이즈는 OS가 자동으로 관리한다.
TCP에 패킷에 receive window size를 담아서 보내는 공간이 존재한다. 여기에 rwnd를 적어서 보낸다.
이때 sliding window값이 항상 rwnd보다 크지 않도록 설정된다. 그러면 버퍼가 넘치는 일이 없을것이다.
Window Size Scale
- The Window Size field is 16 bits -> max 65535 bytes : 현대사회에서 쓰기에는 아직 작다
- 65535 bytes is too small for window size
- Window scale can be defined in TCP options : TCP option을 사용해서 window size를 정의한다. (kind : 옵션의 내용, length : kind+length+value 크기, value : 그때그때마다 다름) SYN에 붙어서 보내지게 된다.
- If window size is 65535 and scale value is 3, RWND is 65535 x 2^3 = 524280 : 만약 value값이 3이면 이와 같이 계산한다.
- Maximum window scale value: 14 : 최대 value값으로 허용되는 것은 14까지이다. 대략 1Gbyte
Silly Window Syndrome
- Receiver’s buffer is almost full : 이미 버퍼가 가득찬 경우
- Small advertised window (e.g. 10 bytes) : sender쪽에 아주 적은 바이트 남은 것을 알려준다.
- Sender sends very small TCP segments : sender은 데이터가 10byte + Header인 패킷을 보내게 된다.
- Small segment -> Large overhead
- Fixed headers (IP: 20 bytes, TCP: 20 bytes)
- E.g. 10 byte data + 40 bytes header -> 80% overhead!! : 결국 overhead가 발생하게 된다.
Segment Size
TCP Segment = TCP header + data, SYN 맺을때 정의할 수 있다.
- Large segments are better
- Maximum Segment Size (MSS) : 헤더를 제외한 데이터부분의 최대사이즈
- A system parameter : 파라미터로 정할 수 있다.
- Default determined by the operating system
- Considers header size and MTU
- Example
- MTU = 1500 bytes (Maximum Tranfere Unit) 을 1500byte로 정의해 놓았다.
- IP header (no option): 20 bytes
- TCP header (no option): 20 bytes
- MSS: 1500 – 20 – 20 = 1460 bytes
Solutions to Silly Window Syndrome
- Nagle’s algorithm (sender)
- If the segment size is too small (smaller than MSS), delay transmission : rcvwin 때문에 segment size가 작은 경우 안보내고 대기하겠다.
- Clark’s algorithm (receiver)
- If receiver buffer space is below a certain threshold, send 0 as advertised window until buffer space recovers : receiver의 버퍼 사이즈가 일정수준이하이면 그냥 0을 보내겠다.
Nagle’s Algorithm
- When the application produces data to send
- If both the available data and the window ≥ MSS
- send a full segment : 정상적인 경우 정상적으로 패킷을 보낸다.
- else
- If there is unACKed data in flight : 아직 ACK이 오지 않은게 있으면 데이터를 보내지 않는다.
- buffer the new data until an ACK arrives
- else : 받은 ACK이 없는 경우(window가 커진걸 모르는 경우)
- send all the new data now : 그냥 데이터를 보낸다.
- (otherwise, the sender will never be able to send because it will not receive ACKs)
대용량 데이터를 보낼때는 안쓰는게 좋다.