[ Network ] TCP

UI SEOK YU·2023년 2월 1일
2

Networks

목록 보기
1/2
post-thumbnail

TCP 에 대하여...

사실 하고 싶은 이야기는 SSL 에 대한 것이다.

프로젝트 당시 SSL 에 대해 자세히 몰라서 배포과정에서 꽤나 애를 먹었기 때문에

SSL 에 대해 탐구하고자 했다. 그러나 공부하다 보니, TCP부터 알아야 하더라.

그래서 TCP에 대한 이야기를 먼저 하고 SSL로 넘어가려한다.

TCP, SSL 에 대한 발표 영상
📺 https://www.youtube.com/watch?v=8rSdXqstN9g


1. TCP의 개요

1-1. OSI 7 계층

  • PC와 PC사이에서 메세지를 전송하려고 하면, 인터넷을 타고 메세지가 이동한다
  • 근데 그냥 이동하는 건 아니고, 택배 보내듯이 절차가 필요한데,
  • 그 절차가 OSI 7계층을 거쳐 이동한다고 보면 된다.
  • OSI 7계층은 3파트로 나눌 수 있다.
    - 물건(데이터)를 다루는 USER 파트
    - 물건을 포장하는 KERNEL 파트
    - 택배가 택배차량을 타고 이동하는 HardWare 파트

1-2. HTTP와 TCP

  • 각각의 계층에는 일정한 양식과 행동 절차등의 '규칙'이 있다.
  • 그 규칙을 프로토콜이라고 한다.
  • 프로토콜은 여러 종류가 있다.
  • 우리가 흔히 쓰는 HTTP는 Transport 계층으로 보낼 때, TCP 라는 프로토콜을 준수한다.

  • Application 계층에서 Transport 계층으로 보낼 때, HTTP와 TCP 프로토콜을 사용한다고 하자.
  • HTTP 를 준수한 메세지는 TCP프로토콜에 의해 포장되어 다음 계층 (Network)으로 보낸다.

  • 전반적인 전송과정을 다시 그려보면 이렇게 보내는 측에서 택배(메세지)를 단계마다 포장하고,
  • 받는 쪽에서도 단계마다 포장을 해체하여 최종적으로 택배(메세지)물건을 받는다.
  • 우리는 이 계층에서 TransportTCP 에 대해 알아볼 것이다.
  • 그럼 저 "포장" 을 자세히 살펴보자. 윗윗 그림에서 TCP 추가정보 란 무엇일까.

1-3. TCP 세그먼트 구조

  • 위 표에서 파란색 부분이 TCP 추가정보 이며, 이것을 TCP 세그먼트 헤드라고 한다.
  • 내용이 많은데, 간단히 말하면 택배를 보내는 주소지, 수령여부 등이 적힌 '전표' 같은 것이다.
  • 각각의 내용은 2,3,4장에서 자세히 설명한다. 일단은 위 그림을 계속 참고할 것임을 유념하자.

1-4. TCP의 특징

  • HTTP가 TCP를 사용하는 이유가 있다.
  • 연결지향형
  • 신뢰적 데이터 전송
  • 흐름제어
  • 우선은 3가지 특징이 있다는 것만 알자.
  • 각각의 특징이 어떤 지 다음 장에서 자세히 알아보자

2. TCP의 연결

2-1. 연결지향형

  • 앞 장에서 TCP 가 연결지향형이라고 했다.
  • 메세지를 줄 때 휙 던지고 끝나는게 아니라, 제대로 받았는지 수신을 확인하며 "마주보고 이야기" 하겠다는 것이다.
  • 마주보고 이야기 하기전에, 인사하는 과정이 있다. 3-Way-Handshake라고 한다.
*** 추가 설명 ***

- 프로토콜의 개념을 잘 모르는 채 이 내용들을 보면, 실질적으로 어떻게 같은 계층끼리 이야기 하겠다는 것인지 
  잘 와닿지 않을 수 있다.
  
- TCP가 연결지향 통신을 한다는 것은 타 계층은 알지 못한다.

- 위에서 본 택배 포장하고 벗기는 것처럼, 각 층에서는 같은 계층이 포장한 것만 벗겨서 확인하기 때문에.
  (자기한테 해당하는 포장만 본다)

- 그러니까 타 계층에서는 깔 일 이 없고 같은 층에서만 보므로, 그 층에서 봐야할 정보들을 적어두면, 
  상대와 나의 각 층 (transport---transport)은 서로 정보를 주고받으며 연결 될 수 있다는 이야기다. 
  
- 그래서 앞으로 메세지를 주고받는 것을 그림으로 표시할 때도 모든 계층을 다 그리지는 않고,
  특정계층의 입장에서 메세지를 주고받는 형태로 표시한다.

2-2. 3-Way-Handshake

  • 그림은 아래로 갈 수록 시간이 흐른다고 생각하면된다.

  • Transport 계층에서TCP프로토콜로 통신할 때,

  • 클라이언트는 서버에 인사악수를 건넨다. (ㅎㅇㅎㅇ)

  • 서버는 클라이언트와 통신할 소켓을 열어준다.

  • 클라이언트는 서버가 열어준 소켓에 대고 이야기를 한다.

  • 자세히 그려보면 아래와 같다.

  • 클라이언트에 접속을 받기 위해 항상 열려있는 소켓을 welcome socket이라고 한다.
  • 클라이언트는 각 전용소켓으로부터 데이터를 주고 받는다.
  • 이렇게 TCP는 1:1 연결지향형 통신을 한다.

그러면 이제 3-Way-handshake 를 자세히 보자.

  • 아까 그 ㅎㅇㅎㅇ 그림을 자세히 표현한 내용이다.
  • SYN, ACK, seq 가 등장한다.
  • 먼저 1-3의 TCP 세그먼트 구조를 다시한번 보고오자.
  • SYN : 연결 요청 비트
  • ACK : 응답 비트
  • seq : (=sequence:순서), 세그먼트구조 두 번째 줄의 '순서번호'에 해당

위에서 부터 차례로 설명하면

  • 1단계 (ㅎㅇㅎㅇ 내 말 들려?)
    - SYN = 1 : 지금 보내는 이 세그먼트가 연결을 요청한다는 것을 알림
    - seq = client_isn : 내(=클라이언트)가 앞으로 보낼 메세지에 순서를 적어서 보낼 건데,
    시작번호는 client_isn (어떤 숫자일 것이다.) 임을 알려줌

  • 2단계 ( ㅇㅇ 들려. 너도 내 말 들려? )
    - SYN = 1 : 나도 너에게 연결을 요청한다.
    - ACK = client_isn+1 : 너가 보낸 메세지를 잘 받았다. 그러니 client_isn의 다음 메세지인 client_isn+1 번째 메세지를 보내달라.
    - seq = server_isn : 내(=서버)가 앞으로 보낼 메세지의 순서번호 시작은 server_isn 이다. (얘도 마찬가지로 어떤숫자임. clinet_isn과는 다른 숫자)

  • 3단계 ( ㅇㅇㅇ 잘 들림~ )
    - SYN = 0 : 연결요청은 끝났으니, 이 플래그 값은 0으로 바꿈.
    (즉, 지금 이 3번째 세그먼트는 연결을 '요청'하는 세그먼트가 아니다.)
    - ACK = server_isn+1 : 너가 보낸 메세지를 잘 받았다. 그러니 server_isn의 다음 메세지인 server_isn+1 번째 메세지를 보내달라.
    - seq = client_isn+1 : 그리고 지금 보내는 이 세그먼트의 순서번호는 client_isn+1 이다.

이렇게 3번 주고 받으면 비로소 연결 설정이 끝난다.


3. TCP의 통신

3-1. 신뢰적 데이터 전송

네트워크를 통한 데이터 전송은 다양한 원인으로 데이터가 변형될 수 있다.

  • 데이터 전송과정에서 '물리적인 요인'으로 데이터가 망가지거나,
  • 특정 라우팅과정에서 버려지거나,
  • 전송경로에 따라 도착 순서가 달라지는 등..

만약 이런 상황을 가정해 두지 않고 아무 대책도 세우지 않는다면, 정상적인 데이터 전송이 될 수 없다. 메세지를 받는 입장에서는 이게 맞는 정보인지 신뢰할 수 없다.
메세지를 신뢰한다는 말은 다음과 같다.

  • 데이터가 손상되지 않는다.
  • 데이터의 손실이나 중복이 없다.
  • 데이터의 순서가 유지된다.

그래서 TCP는 신뢰적인 데이터 전송을 위해 마련한 대책이 존재한다.

  • 확인 응답 ---- (3-2)
  • 타이머 ------ (3-3)
  • 순서번호 ---- (3-4)


3-2. 확인응답

TCP는 보낸 메세지에 대한 확인응답을 받는다. 즉 수신여부를 확인한다.
이미 " 2-2. 3-Way-handshake" 에서 그 과정을 보았다.
바로 ACK를 활용하는 방법이다.

3-2-1. ACK

  • ACK는 수신자로부터 그 값을 받는다.
  • 송신자가 A라는 메세지를 보냈다면, 수신자로부터 "A받음" 이라는 신호가 와야한다는 것이다.
  • 그 "A받음" 신호를 적는 칸이 ACK 이다.

이 ACK를 활용함에 따라 다음과 경우를 생각해 볼 수 있다.

  • 송신한 메세지가 수신자에게 도착하지 않을 때
  • 수신자가 메세지를 받았으나, 수신자가 보낸 ACK가 송신자에게 도착하지 않을 때

상대로부터 ACK가 오지 않는다면 송신자의 입장에서는 위 두 가지 경우를 고려할 수 있다.
따라서 송신자는 ACK가 되돌아 오지 않으면, 해당 메세지를 다시 수신자에게 보낸다.
그렇게 되면 메세지가 중간에 누락되는 문제를 해결할 수 있다.



3-4. 타이머

그런데, ACK를 '언제까지' 기다려야 오지 않는다고 판단 할 수 있을까?
ACK를 무작정 기다릴 수는 없을 것 같다. '언제까지'의 기준이 필요하다.
그래서 타이머 를 활용한다.

3-4-1. RTT

송신자는 RTT를 기준으로 언제까지 기다릴지 정한다.

  • RTT ( Round Trip Time ) : 송신자가 보낸 메세지가 수신자에게 도착하고,
    수신자로부터 메세지를 받았다고 송신자에게 응답이 되돌아오는 시간

    *** 참고 ***
    RTT는 라우터의 혼잡 및 종단시스템에서의 부하가 실시간으로 변하기 때문에, 시시각각 그 값이 변한다. 
    그런환경을 반영하여 추정된 RTT의 (EstimatedRTT) 도출은 측정되는 RTT의 가중치를 두어 계산한다.
  • 송신자는 RTT 정도면 ACK가 올 것이라고 생각하니 RTT+여유시간 동안 기다린다.

  • 그럼에도 ACK가 되돌아오지 않으면, 타임아웃 으로 간주한다.

  • 타임아웃 이 되면, 송신자는 수신자에게 해당 메세지를 재전송한다.



3-3. 순서번호

그런데 하나보내고 하나 응답받고, 하나보내고 다시 응답받고 하는 행동은 너무 느리고 비효율적인것 같다.
메세지를 연달아 여러 개를 보내면 좀 더 빠르게 처리할 수 있지 않을까?
이 처럼 '전송 후 대기' 를 일일히 하는 것 대신에, 여러개의 패킷을 전송하는 것을 파이프라이닝 이라고 한다.

3-3-1. 파이프라이닝

  • 파이프 라이닝은 전송 후 대기 기법에 비해 훨씬 더 많은 시간을 단축 할 수 있다.

  • 위 그림에서도 알 수 있듯이, 병렬처리 된 만큼 시간이 단축된다.

  • 얼마나 병렬적으로 처리할 것인지 N개의 개수를 정한다. 이것을 윈도우 크기 라고 한다.

  • 패킷이 여러 개가 연달아 가므로, 패킷의 순서를 표시한다.

  • 순서는 TCP 세그먼트 구조에서 순서번호 에 표기한다.

  • 2-2. 3-Way-handshake 의 마지막 절차그림에서 seq가 그것이다.

  • 순서번호를 활용한다면, 수신자는 패킷을 한번에 여러 개 받아도, 순서에 맞게 조립할 수 있다.

3-3-2. 빠른 재전송

만약 송신자가 1,2,3,4 번의 패킷을 보내고,
수신자가 1,2,4 의 패킷만 받았다고 할 때, 3번을 못받았다고 어떻게 알려줄 수 있을까?

수신자는 위와같이 ACK에 받아야 할 패킷의 순서번호를 계속해서 응답한다.

  • 10 번 받음. 이제 11번 필요함.(ACK 11)
  • 엥? 12번? 아니 11번 안왔다고. 11번 필요함. (ACK 11) << 중복 ACK
  • 13번이 왔네.. 11번 필요하다니까..(ACK 11) << 중복 ACK

그럼 송신자는 ACK=11 을 3번 연달아 받는다.
정상적으로 수신자가 다 받았다면 10 11 12 .. 이런식일 텐데, 11번이 연속으로 온 것은 수신측이 11 번 패킷을 정상적으로 못 받았음을 유추할 수 있다.
따라서 11번 패킷에 대한 타임아웃이 일어나기 전에 바로(빠른) 재전송을 한다.
수신측은 11번을 받고, 아까 13번까지 받아놨으니, 응답으로 13번 패킷을 달라고 ACK를 보낼 것이다.
결과적으로 수신측은 누락 없이 패킷을 받을 수 있다.

3-3-3. GBN / SR

사실 TCP의 순서번호 및 재전송 과정을 알기 전에, 재전송 프로토콜인 GBN과 SR에 대한 배경지식이 필요하긴 하다.
위에 설명한 내용은 GBN과 SR이 결합된 TCP의 재전송 프로토콜에 대해 풀어서 설명했다.

  • GBN (Go-Back-N) : 잃어버린 패킷번호부터 윈도우 크기 만큼 다 다시보냄
  • SR (Selective-Reapeat) : 잃어버린 패킷만 선별해서 다시보냄


3-5. 흐름제어

TCP는 위에서 설명한 신뢰적 전송 뿐만 아니라, 흐름제어 서비스를 제공한다.

3-5-1. 흐름제어와 혼잡제어


흐름제어와 혼잡제어는 효율적인 데이터 전송속도를 위하여 송신자의 내보내는 속도를 조절한다.
역할은 비슷해 보이지만, 목적이 다르다.

  • 흐름제어 는 수신자의 상태에 따라 송신자의 보내는 속도를 맞추고,
  • 혼잡제어 는 네트워크 환경에 따라 여러 송신자들이 보내는 속도를 조절시킨다.

3-5-2. 흐름제어의 역할

  • 송신자 쪽에서 수신자쪽으로 패킷들을 보낼 때, 수신자가 받아서 처리할 수 있는 용량에 한계가 있을텐데 (버퍼의 크기), 그 이상 받게 되면 패킷을 보내도 오버플로우 되어 의미가 없다.
  • 즉 수신자의 애플리케이션이 패킷들을 읽는속도와, 송신자의 Transport 계층에서 패킷들을 보내는속도를 맞춰야만, (정확히는 '송신자에서 보내는 속도'를 '수신자가 읽는 속도'보다 느리게 해야만) 넘치지 않고 처리가 가능할 것이다.
  • 그 기준을 수신 윈도우 크기 라고 한다.

  • 수신자는 패킷을 받았다고 응답을 보내면서, 현재 여유가 얼마나 남았는지 같이 적어서 보낸다.
  • 송신자는 수신자가 알려준 여유공간을 확인해서 거기에 맞춰 패킷을 보낸다.
  • (마지막으로 보낸 패킷번호 - 수신응답이 온 패킷번호) 는 아직 전송해서 날아가고 있는 패킷들의 양일 것이다. 이 보내는 양을 수신자의 여유공간보다 크지 않도록 조절한다.
  • 이렇게 보내는 양을 조절하는 것이 흐름제어 이다.

*** 참고 ***
만약 그 여유공간이 0 일 때, 수신자가 여유공간이 없다고 말한 후 패킷을 읽고 공간을 비워내더라도 
송신자는 여유공간이 생겼다는 메세지를 받을 답장이 없으므로, 무한 대기상태에 빠질 수 있다.
그래서 송신자는 여유공간이 0이어도, 1바이트짜리 세그먼트를 계속 전송한다. 

3-6. 혼잡제어

  • 혼잡제어는 흐름제어에서 언급 했다시피, 라우팅 환경에 따라 송신속도를 조절하는 기능이다.
  • 라우팅 환경이 혼잡하면 '덜' 보내고,
  • 라우팅 환경이 여유로우면 '더' 보낸다.
  • '혼잡하다' 의 기준은 '세그먼트의 손실'로 간접적으로 판단할 수 있다.
    ( ex : 타임아웃, ACK 중복응답 등 )

3-6-1. 슬로우 스타트

  • 혼잡도를 고려한, 한 번에 보내는 세그먼트의 양을 혼잡 윈도우 크기 라고한다.
    ( 흐름제어에서 수신자의 환경에 따라 보내는 양을 윈도우 크기로 정하는 것과 비슷하다 )
  • TCP 연결이 시작된 후, 혼잡제어 윈도우 크기를 1MSS 부터 시작한다.
  • 한번 송신을 했는데 혼잡하지 않다면, 보내는 양을 2배 늘린다.
  • 혼잡하기 전까지 늘어나는 혼잡 윈도우 크기 는 지수형태로 커진다.


3-6-2. 혼잡 회피

  • 그러다 혼잡 상황을 마주치면, 선을 하나 그어놓는다. (송신자의 메모장 참고)
  • 선은 혼잡 윈도우 크기의 1/2 이다. 이걸 슬로우스타트 임계치 라고한다.
  • 그리고 혼잡 윈도우 크기는 처음부터 다시 시작한다.
  • 이렇게 혼잡이 예상되는 구간 (슬로우스타트 임계치) 에서 보수적으로 윈도우 크기를 늘려나가는 것을 혼잡회피 라고 한다.

3-6-3. 빠른 회복

  • 슬로우스타트와 혼잡회피는 TCP 통신 설정에서의 필수 사항이지만, 빠른회복은 권고사항이다.
  • 3-6-2. 혼잡 회피에서, 혼잡윈도우크기를 1부터 시작하지 않고
  • 슬로우스타트 임계치부터 시작하여 1씩 증가 시킨다.
  • 혼잡 회피와는 다르게 슬로우스타트 임계치부터 다시 시작하는 것을 빠른회복 이라고 한다.



4. TCP의 종료

  • 아무튼 TCP는 위의 기술된 프로토콜과 기술을 활용하여 통신을 한다.
  • 1:1 로 연결하여, 어떻게 해서든 보내고 어떻게 해서든 데이터를 받아서 완성시키는 것이다.
  • 이제 보내고 받을 거 다 했으니, 연결을 종료하고자 한다.

4-1. 4-Way-Handshake

  • TCP 연결의 종료는 연결 시작할 때와 비슷하다.
  • 이번엔 4번 대화가 왔다갔다 하므로, 4-Way-Handshake 이다.

  • TCP 세그먼트의 FIN 플래그로, 연결 종료를 요청한다.
  • 수신 응답을 받는다.
  • 다른 쪽에서도 FIN 플래그로, 연결 종료를 요청한다.
  • 마찬가지로 반대쪽에서 수신응답을 받는다.
  • 연결이 종료된다. 하지만 못 받은 데이터가 있을 수도 있으니 몇십초 간 더 대기한다.

< 요약 >

  • TCP는 Transport 계층의 프로토콜로써,
  • 3-Way-Handshake 를 통해 연결지향형 통신설정을 하고
  • 파이프라이닝, 타이머, 확인응답을 이용하여 신뢰적인 데이터 전달을 한다.
  • 또한 수신자 및 네트워크 환경에 따라 흐름제어, 혼잡제어로 전송속도를 조절 한다.

5. TCP의 단점

5-1. 보안성 문제

  • 이런 TCP를 활용하면 모든데이터를 신뢰적으로 주고받을 수 있을 것 같다.
  • 하지만 네트워크 세상은 그렇게 평화롭지 못하다.
  • 누군가 악의적인 목적을 가지고 데이터의 변경, 삭제, 탈취 등을 행한다면,
    그것을 막을 수 있는 기능은 TCP 에는 존재하지 않는다.

5-2. 예시

  • 전송되는 패킷들을 중간에 가로채어 열어보고 다시 안본 것 처럼 전달한다면?
  • 그 안에 들어있는 데이터들이 개인정보와 같이 민감한 자료라면?
  • 서버인줄 알고 패킷을 보냈는데 알고보니 위장한 악성사이트였다면?

등등..
TCP에는 보안적으로 취약한 부분이 존재한다.
이를 보완하기 위해 Transport 계층과 Application 계층을 이어주는
보안 출입국을 하나 세운다. 그것이 SSL이다.
다음 장에서 SSL에 대하여 알아보자.

0개의 댓글