티스토리 뷰
TCP 는 flow control service 를 제공한다.
Flow control service의 지상목표는 sender 가 receiver 의 buffer를 overflow 시키지 않도록 해주는 것이다.
그래서, Flow control service 를 speed matching service 라고 말 할 수 있다.
sender 에서 produce 하는 속도와 receiver 가 consume 하는 속도를 매칭시켜서 receiver 가 overflow 되거나
지나치게 위축되어서 둘 사이의 Link capacity 를 충분히 활용하지 못 하는 상황을 방지해서 최적의 균형점을
찾아주는 service 인 것이다.
TCP는 sender 측에서 receive window 라는 변수를 유지함으로써 근본적으로 작동할 수 있게 된다.
이 receive window 변수의 목적은, receiver 가 버퍼에 얼마만큼의 여유공간이 있는지 알려주는 변수이다.
Host A 를 보내는 측, Host B 를 받는 측 이라고 하면
Host B는 A에게 보내는 세그먼트마다 자신의 rwnd(receive window)를 갱신해서 알려준다.
그러면 Host A는 LastByteSent - LastByteAcked <= rwnd 인 범위 내에서 데이터를 보냄으로 써,
connection 동안에 B를 overflow 시키지 않는것을 보장한다.
만약에 Host B의 receive buffer 가 가득차서, 즉 rwnd = 0이 되어서 A에게 이 사실을 알리고나서, B 또한 A에게 보낼 데이터가 없다고 한다면
어떻게 상황이 진행될까?
B는 일정 시간이 지난 후에 process에 의해 buffer 가 비워질 것 이다. 하지만 B는 A에게 보낼 데이터가 없기 때문에
A는 B가 available 하다는 사실을 계속 모를 것이 분명하다. 따라서 A는 block 된 상태로 아무 데이터도 보내지 못하고 있을 것 이다.
이러한 상황을 해결하기 위해 TCP 명세에서는, B의 receive window size가 0 일 때, A로 하여금 지속적으로
1 byte 의 data byte를 가진 segment 를 보내도록 하고 있다. 따라서 지속적으로 이 자그마한 세그먼트를 보내보다가
B의 buffer 비워져서 A가 데이터를 보낼 수 있게 된다면, A는 그제서야 원하는 데이터를 보낼 수 있게 된다.
○ TCP Connectin 관리
1.
클라이언트의 TCP 는 서버 TCP에 특별한 TCP segment 를 보낸다. 이 특별한 TCP segment 에는 아무런 application layer의 데이터도 담겨있지 않다.
다만, segment header의 flag bit가 set 되어있다.
즉 위의 빨간색으로 강조한 SYN bit가 1로 set이 되는 것 이다. SYN은 Synchronize 의 약자이다.
클라이언트는 랜덤하게 intial sequece number를 선택한다. 여기서 왜 0부터 시작하지 않고 initial sequence number를
선택하는지가 의문이었었는데, 그 이유는 Security 때문이다. 만약에 SYN 이 0부터 시작하는 것으로 고정되어 있다면
Connectin spoofing, Connection resetting, data injection 같은 공격에 취약해진다.
항상 악용하는 사람들은 있기 때문에 어쩔 수 없지만 , 보안 때문에 소모되는 리소스(Network bandwidth, CPU clerk) 은 정말 아깝다.
ADSL, Stack canary 나 암호화 하는 비용(AES, RSA..), CORS
본론으로 돌아가서, random 하게 generate 된 sequence number를 sequence number field 에 넣고 IP datagram으로
만들어서 서버로 보낸다.
2.
TCP SYN을 포함한 segment 가 서버에 도착하면, 서버에서는 TCP segment 를 추출해서 해당 connectioni에
TCP buffer와 variable 들을 할당하고, connection-granted segment를 클라이언트에 보내주게 된다.
당연히, connection-granted segment 또한 application layer의 data를 포함하지 않는다.
대신에 중요한 3가지 정보를 포함하는데
ㄱ. 1로 설정 된 SYN bit
ㄴ. 클라이언트에서 보낸 sequence number(client_isn)에 1이 더해진 값으로 세팅 된 acknowledgement field
ㄷ. 서버만의 고유한 initial sequence number(server_isn) 그리고 이것을 sequence number field에 넣는다
이 connection-granted segment 를 SYNACK segment 라고도 부른다.
여기까지 되면, 서버와 클라이언트를 의인화 시켜보면
클라이언트: 너랑 통신하고 싶어, client_isn 은 76 이니깐 통신할 생각이 있으면 답장 줘
서버: 네가 보낸 SYN packet 은 잘 받았어, 거기에 써있는 client_isn 인 76도 잘 받았어, 좋아 너랑 통신할께
내 server_isn 은 47이야, 그리고 네가 보낸 요청을 잘 받았다는 증거로 네가 보낸 client_isn 에 1을 더해서
보내줄테니깐 확인해
3.
클라이언트가 SYNACK segment 를 받으면 클라이언트도 또한 buffer 와 variable을 할당합니다. 그리고나서
서버가 SYNACK segment에 껴넣은 server_isn 에 1을 더합니다. 그리고 SYN bit를 0로 설정합니다.
이제, 클라이언트는 자기가 보내고자 하는 데이터를 실어서 서버에 보낼 수 있습니다.
위의 세 번의 과정이 그 유명한 TCP 의 Three-way Handshake입니다.
○ TCP Connectin 의 종료는 어떻게 할까?
connection 의 시작이 있으면 끝도 있는것이 당연하다. TCP 는 어떻게 연결을 종료할까?
빨간색으로 강조해놓은 필드의 이름을 보아하건데, FINISH 의 약자일테니, 용도가 뻔히보인다.
클라이언트에서 이 FIN 필드를 1로 세팅해서 서버에 보내면, 서버는 이것을 감지하고 클라이언트에 연결을 종료한다는
acknowledgement segment를 보내준다. 그리고나서 서버는 자신만의 shutdown segment를 보내주는데 이 segment
또한 FIN 필드가 1로 세팅되어 있다.
클라이언트는 서버가 보낸 shutdown segment를 읽어보고 연결을 종료가 무사히 되었음을 확인한다.
○ TCP Connectin 의 생애주기
이처럼 TCP connection도 생애주기가 존재한다.
client에서 TCP 는 처음에 CLOSED 상태로 시작한다. 클라이언트측에서 SYN을 서버에 보내면 클라이언트의 TCP는
SYN_SENT 상태가 된다. 그리고 서버로부터 연결이 성사되었다는 acknowledge를 받게되면, ESTABLISHED 상태로 바뀐다.
이 상태에서 클라이언트가 연결을 종료하고자 한다면, FIN_WAIT_1 상태로 바뀌게 되며, 서버에서 연결종료에 대한 acknowledge를 받게되면 FIN_WAIT_2로 바뀐다.
그리고나서 서버에서 FIN 필드가 1로 세팅된 Shutdown segment를 받을 때 까지 기다린다.
이 Shutdown segment를 받게되면 TIME_WAIT 상태로 바뀌게 된다. TIME_WAIT 을 얼마나 유지할 것인가는 구현에 따라 다르지만
일반적으로 30초, 1분 혹은 2분정도 이다.기다린 후에, CONNECTION 은 정식으로 닫히게 되며 connection을 위해
할당해두었던 모든 자원들을 할당 해제한다
그런데, TIME_WAIT 의 용처를 아무리 상상해봐도 떠올려지지가 않았다. 그래서 검색을 해 보았는데
엄청 좋은 글을 찾을 수 있었다. (http://docs.likejazz.com/time-wait/) 꼭 TIME_WAIT 뿐만 아니라 이 글에 대한 심화적인
내용도 많이 포함되어 있으니, 꼭 읽어보길 권한다.
'네트워킹' 카테고리의 다른 글
Hot potato Routing (0) | 2020.06.22 |
---|---|
Network Layer (0) | 2020.06.21 |
TCP Congestion control (1) | 2020.06.19 |
Transport Layer (0) | 2020.05.26 |
- Total
- Today
- Yesterday
- CMake 반복문
- CMAke 파일이름 추출
- CMake run proto compiler
- CMake get_filename_Component
- 14714 어플
- 복습 계획어플
- 14714 복습법
- get_filename_component
- CMake probouf
- 14714 review
- CMake get file name
- buffer-over-flow
- react-native
- function pointer overflow
- 함수포인터 오버라이트
- 14714 어플리케이션
- CMake for문
- 14714 앱
- 14714 플래너
- 복습 어플
- aws 프리티어 요금청구
- 14714 공부법 어플리케이션
- 14714 공부법
- 토리파 공부법
- CMake for
- aws 청구문의
- CMake run protoc
- review reminder
- CMake 기초
- CMake 강좌
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |