TCP 연결 설정 및 종료 과정과 흐름제어/혼잡제어/오류제어

Simcurity·2023년 4월 1일
1

네트워크

목록 보기
1/1
post-thumbnail

1. TCP(Transmission Control Protocol)란 무엇인가

IT에 종사하는 사람들이라면 네트워크 7계층(OSI 7 LAYER)이라는 것을 적어도 1번은 들어보았을 것입니다. 이 중에 4계층인 전송 계층(Transport Layer)은 종단간의 데이터 교환을 신뢰성있게 전송할 수 있게 해주는 계층입니다. 여기서 말하는 종단이란 사용자와 사용자가 될 수도 있고, 서버와 클라이언트가 될 수도 있습니다. 즉 데이터를 주고 받는 상호관계가 되는 모든 인터넷 상의 관계입니다.

TCP(Transmission Control Protocol)란 네트워크 계층의 4계층 프로토콜로 종단 간의 신뢰성있는 데이터 송·수신을 위한 하나의 전송 방식입니다.

여담으로는 TCP가 개발된 것은 바야흐로 1960년대 미국과 소련의 냉전시절이 한창일 때 미국에서 아무것도 존재하지 않아도 신뢰성있는 통신을 하기위해 개발한 프로토콜이라고 합니다. 그만큼 현재까지 쓰일정도로 신뢰성을 극대화한 프로토콜이란 것입니다. 그래서 원래 OSI 7 LAYER보다 TCP 4 LAYER가 먼저 정의되었다고 합니다. (OSI 7 LAYER는 1970년대에 정의)

1-1) TCP의 흐름제어

TCP는 흐름제어 기능을 합니다. 흐름제어란 TCP 프로토콜 안에 window size라는 필드가 있는데 이 필드는 현재 자신이 수용 가능한 데이터 수신 버퍼 크기를 알려주는 역할을 해줍니다.
이로써, 원활한 데이터 송·수신을 할 수 있게 해줍니다.

이 때 만약 한 쪽에서 데이터를 받아야 하는데 window size를 속여 데이터를 받기를 거부하며 상대에게 계속 연결 유지를 하게 한다면 어떻게 될까요? 이는 SLOW HTTP READ DoS 공격으로 가용성을 떨어뜨리는 공격 중 하나입니다.

1-2) TCP의 혼잡제어

TCP는 혼잡제어 기능을 합니다. 혼잡제어란 데이터를 보낼 때마다 각 타이머가 돌아가는데 만약 타이머 안에 ACK신호가 오지 않는다면 데이터를 다시 보냅니다.

또 다른 방법은 슬라이딩 윈도우 기법으로 데이터를 쭈루룩 보내다가 만약 1번 데이터가 전송 중 실패했다면 수신 측은 다음 데이터를 받을 때마다 "1번 보내", "1번 보내"라고 보냅니다.
그러다가 3번의 신호가 오면 송신 측은 1번 데이터를 다시 보냅니다. 타이머가 초과되어 재전송 하는 것보단 빠르므로 이를 덜 혼잡한 상태라고 합니다.

1-3) TCP의 오류제어

TCP는 오류제어 위해 재전송 기반 오류 제어 ARQ(Automatic Repeat Request)를 사용합니다.
Stop And Wait, Selective Repeat, Go Back N, 등의 방식을 이용해 오류를 제어합니다.

Stop And Wait 방식은 데이터를 하나 보내고 ACK를 받는 방식으로 송신 측에서 데이터를 하나 보내고 일정 시간안에 ACK가 오지 않는다면 오류가 났다고 판단하고 다시 보냅니다.

Selective Repeat 방식은 윈도우 사이즈 만큼의 데이터를 보내고 응답을 기다립니다. 만약 1,2,3,4 데이터를 보냈는데 3번 데이터가 오류시 3번만을 다시 보내라는 응답을 받고 3번의 데이터만을 보냅니다.

Go Back N 방식은 데이터를 하나를 보내면 윈도우 사이즈가 1씩 줄어듭니다. 그리고 0이 되면 응답을 기다립니다. SR방식과 비슷하지만 만약 1,2,3,4 데이터를 보냈는데 3번이 오류가 나면 3번부터 4번까지의 데이터를 다시 보내야한다는 차이점이있습니다. 즉, 제대로 보낸 패킷도 다시 보내야 합니다.

 

2. TCP 신뢰관계를 형성과 종료는 어떻게 할까?

만약 A가 B에게 중요한 것을 전달해주어야 한다고 가정해봅니다.
그런데 A에게 이것이 너무나도 중요해서 B에가 찾아가 "너 B맞지?" 라고 물어봅니다.
그러면 B는 A에게 "어 나 B맞아" 라고 말을하고
다시 A는 B에게 "알겠어" 라고 말하고 중요한 것을 전해준다고 생각해봅니다.

이것은 실제 TCP 신뢰관계 형성 과정을 묘사한 것입니다.

2-1) 3-way handshake

1. 첫번째 단계

A가 처음에 B에게 연결을 요청할 때 TCP 플래그(UAPRSF가 있다) 중 SYN 만을 설정한 패킷을 보냅니다. 이때 순서번호(sequence.number)는 임의의 값으로 설정하고 acknowledge.number은 상대가 다음에 보내야 할 넘버를 설정하는 것인데 아직 B에게는 받은 순서번호가 없으니 값을 비우고 보내줍니다.

2. 두번째 단계

그러면 A의 상태는 SYN_SENT상태가 돼고 SYN 패킷을 받은 B는 SYN+ACK 플래그를 설정한 패킷을 보냅니다. 이때 순서번호는 임의의 값으로 지정하고 acknowledge.number은 A에게 받은 순서번호 +1 값을 지정한다. 그리고 B는 SYN_RECV 상태가 됩니다.

3. 세번째 단계

해당 패킷을 받은 A는 ESTABLISHED상태가 되고 마지막으로 ACK 플래그를 설정한 패킷을 보냅니다.
이때는 마찬가지로 전에 보낸 순서번호 +1과 acknowledge.number은 B에게 받은 패킷의 순서번호 +1을 설정해서 보냅니다.

4. 신뢰관계 성립

해당 패킷을 받은 B도 ESTABLISHED상태가 되고 이제 A와 B는 신뢰적인 상호관계가 된것입니다.
이 과정을 3-way handshake라고 합니다.
이렇게 신뢰관계를 형성하고나면 데이터를 주고 받을 수 있게 됩니다.

보안 이야기

그런데 만약 C라는 누군가가 이 과정을 보고있다가 B에게 sequence.numberacknowledge.number을 예측한 값으로 보낸다면 어떻게 될까요?
그러면 B는 C에게 신뢰관계를 형성하게 되고 이 때 올바른 상대는 sequence.numberacknoledge.number가 예상하지 않은 값이 오기 때문에 ACK STORM이라는 현상이 발생합니다. 이렇게 신뢰관계를 이용하는 공격을 TCP 세션 하이재킹이라고 합니다.(전 세계적으로 유명하신 케빈 미트닉이라는 해커 분이 처음 악용)
보안적인 이야기는 나중에 더 올리도록 하겠습니다.


그럼 이제 연결을 종료하는 과정을 알아보겠습니다.

2-2) 4-way handshake

1. 첫번째 단계

연결을 끊기를 요청하는 쪽에서 먼저 FIN+ACK 패킷을 보냅니다.
그러면 A는 FIN_WAIT_1상태가 됩니다.

2. 두번째 단계

B는 패킷을 받고 ACK 패킷을 보냅니다. 그리고 CLOSE_WAIT 상태가 되는데 이 상태는 상위 계층의 어플리케이션 등에서 이제 연결을 끊기 위한 준비 작업을 하는 시간이라고 보면됩니다.

3. 세번째 단계

모든 준비 작업을 마쳤으면 FIN+ACK 패킷을 A에게 보낸다 그리고 B는 LAST ACK만을 기다리는 LAST_ACK 상태가 됩니다.

4. 네번째 단계

A에서 마지막 ACK를 보내고 바로 CLOSED 상태가 되는 것이 아니라 TIME_WAIT 상태로 들어가며 타이머가 돌아갑니다.
이유는 만약 마지막 ACK 패킷이 유실되거나 B에게 도달하지 못한 경우 B에서는 다시 요청을 하기 때문에 일정 시간 동안 연결을 닫지 않고 기다리다가 연결을 종료하기 위함입니다.

네트워크는 끝이 없다고 알고 있습니다. 오늘 정리한 내용은 TCP에 대해 극히 얕은 내용입니다. 더 깊이 배우기 위해 열심히 공부해야겠습니다.

1개의 댓글

comment-user-thumbnail
2023년 4월 3일

오! 유용한 정보 감사합니다 ㅎㅎ

답글 달기