기존 IP의 문제점
네트워크 계층의 IP는 신뢰할 수 없는 통신과 비연결형 통신을 수행한다는 한계가 있습니다.
왜 신뢰할수 없는 통신일까요?
- 데이터의 전달여부와 상관없이 전송합니다.
- 데이터의 순서를 보장하지 않습니다.
- 오류 복구 기능이 없습니다.
- 비 연결형이다. -> 사전 연결 수립 작업을 거치지 않음
왜 비연결형 통신을 할까요?
모든 패킷이 제대로 전송되었는지 확인하고, 연결을 수립하는 작업은 더 많은 시간, 더 많은 부하가 요구 되기 때문입니다.
이러한 문제점을 해결할 수 있는 전송계층의 TCP에 대해 자세하게 알아보고자 합니다.
전송 계층
전송계층은 네트워크 계층와 응용 계층 사이에 위치해 있으며, 신뢰할 수 있는 통신을 가능하게 합니다.
포트 번호를 통해 응용 계층의 프로세스들을 식별하는 역할을 수행합니다.
전송계층은 왜 신뢰할 수 있을까요?
- 연결형 통신을 가능하게 한다.
- 오류 제어, 흐름 제어, 혼잡 제어등 다양한 기능들을 제공하며 순서를 보장
포트란?
포트에 대해 이해하기 쉽게 설명하기 위해 하나의 상황을 가정해보겠습니다.
상황
- A 호스트가 B호스트로 데이터를 전송하고자 합니다.
- A는 B로 데이터를 보낼 때, 같은 IP 주소를 사용하는 여러 애플리케이션 중 어떤 애플리케이션에 데이터를 보내야 할지 모르는 상황
- B 호스트는 하나의 IP를 공유하는 다양한 애플리케이션을 실행 중이기 때문에, 단순히 IP 주소만으로는 구별 불가능
이러한 상황을 해결하기 위해 포트가 존재한다.
쉽게 말해, 포트는 데이터를 전달할 때, 같은 IP의 특정 애플리케이션을 식별할 수 있는 정보를 제공합니다.
포트 번호
포트번호는 16비트로 표현가능하며 0부터 65535번까지 가능합니다.
번호 범위에 따라 세 종류로 나뉘어 집니다.
- 잘 알려진 포트 : 0~1023
- 범용적으로 사용되는 애플리케이션 프로토콜이 사용하는 포트번호
- 등록된 포트 : 1024 ~ 49151
- 덜 범용적이지만, 흔히 사용되는 애플리케이션에 할당하기 위해
- 동적 포트 : 49152 ~ 65535
- 사설 포트, 임시 포트 라고도 불린다.
- 인터넷 할당 기관에 할당된 프로토콜이 없으며 관리 되지 않는 포트번호
서버로서 동작하는 프로그램의 포트번호는 사전에 암묵적으로 정해진 경우가 많습니다.
하지만, 클라이언트의 프로그램의 포트번호는 임의의 번호가 할당되는 경우가 많습니다.
크롬 브라우저를 키고 포트번호를 보면 킬 때마다 다른 포트번호를 볼 수 있습니다.
NAPT
기존 NAT의 한계
기존의 NAT(Network Address Translation)는 포트 번호 없이 외부 네트워크와 내부 네트워크를 매핑하는 방식으로 동작합니다.
이 방식에서는 사설 IP 주소와 공인 IP 주소가 1:1로 매핑되어야만 데이터 전송이 가능합니다.
그 결과, 내부 네트워크의 IP 주소 개수와 동일한 공인 IP 주소가 필요하게 됩니다.
이는 공인 IP 주소를 낭비하게 만들어 비용 효율이 떨어지는 큰 단점이 있습니다.
NAPT의 등장
NAPT는 포트 번호와 변환될 IP 주소의 쌍을 기록하여 데이터 전송 시 이를 변환하고 구분합니다.
이 방식 덕분에,
- 다수의 사설 IP 주소를 훨씬 적은 수의 공인 IP 주소로 매핑할 수 있습니다.
- 하나의 공인 IP 주소에서도 포트 번호를 통해 다양한 내부 네트워크 장치와 애플리케이션을 구분할 수 있습니다.
포트 포워딩
문제 상황
네트워크 내부의 여러 호스트가 하나의 공인 IP 주소를 공유하는 경우,
외부에서 내부 네트워크의 특정 호스트로 통신을 시작하려면 문제가 발생합니다.
외부 호스트는 첫 패킷을 전송하기 전에,
- 내부 네트워크의 어떤 호스트로 데이터를 보내야 할지,
- 어떤 포트를 사용해야 할지 알 수 없습니다.
이로 인해 통신의 시작점을 잡는 것이 어려운 상황이 됩니다.
이 문제를 해결하기 위해, IP 주소와 포트 번호 쌍을 미리 특정 호스트에 할당하는 방식이 사용됩니다.
- 내부 네트워크의 특정 호스트에 대해 IP 주소와 포트 번호를 미리 예약합니다.
- 외부에서 해당 IP 주소와 포트 번호로 패킷을 전송하면, 네트워크 장치는 이를 내부의 예약된 호스트로 전달합니다.
ICMP
네트워크 계층에서 IP의 신뢰할 수 없는 전송 특성과 비 연결형 전송 특성을 보안하기 위한 네트워크 계층의 프로토콜입니다.
IP 패킷의 전송 과정에 대한 피드백 메시지를 얻기 위해 사용하는 프로토콜입니다.
주로 2가지의 종류가 있습니다.
- 전송 과정에서 발생한 문제 상황에 대한 오류보고
- 네트워크에 대한 진단 정보
라우터에게 전달된 패킷의 TTL필드가 0이라면 해당 라우터는 송신지 호스트에게 ICMP 패킷을 전송합니다.
네트워크 상의 간단한 문제 진단 및 테스트를 위해 ICMP도 사용됩니다. 정확히는 ICMP의 에코 요청, 에코 응답 메시지를 기반으로 구현되어있습니다.
Echo란?
리눅스 컴퓨터의 터미널 또는 명령 프롬프트에서 사용되는 명령어로, 주어진 텍스트를 화면에 출력하는 데 사용
TCP와 UDP
TCP 통신을 크게 세 단계로 나누면 다음과 같이 구분이 가능합니다.
- 연결 수립
- 데이터 송수신 -> 오류 제어, 흐름 제어, 혼잡 제어
- 연결종료
MSS : Maximum Segment Size, TCP로 전송할 수 있는 최대 페이로드의 크기
MTU - (TCP헤더 + IP헤더) = MSS
MSS의 크기를 고려할 때는 TCP 헤더 크기는 제외.
TCP 세그먼트 헤더 구조
- 송신지포트 와 수신지 포트 : 송신지 또는 수신지 애플리케이션을 구별 하는 포트 번호
- 순서 번호 : 송수된 세그먼트의 순서를 의미
- 확인 응답번호 : 상대가 보낸 세그먼트에 대한 응답으로, 다음으로 수신하기를 기대하는 순서 번호가 명시
- 제어 비트 : 플래그 비트라고 불리며. 현재 세그먼트에 대한 부가 정보를 나타낸다.
- 윈도우 : 수신 윈도우의 크기가 명시된다.
제어비트
제어비트 필드는 기본적으로 8비트로 구성된다. 각 자리의 비트는 각기 다른 의미를 가진다.
- ACK(Acknowledgement) : 세그먼트의 승인을 나타내기 위한 비트
- SYN(Synchronize) : 연결을 수립하기 위한 비트
- FIN(Finish) : 연결을 종료하기 위한 비트
순서 번호와 응답번호
TCP에서 데이터의 올바른 전송과 재조립을 보장하기 위한 중요한 필드입니다.
이 번호는 각 세그먼트의 데이터가 TCP 스트림 내에서 어디에 위치하는지를 나타냅니다. 순서 번호는 바이트 단위로 지정되며, 세그먼트가 네트워크를 통해 전송되는 순서와 무관하게 원래 데이터의 순서를 복원할 수 있도록 합니다.
특징
- 초기 순서 번호 ( ISN, Initial Sequence Number)
- TCP 연결이 시작될 떄 각 통신 주체가 사용하는 시퀸스 번호의 시작점
- 임의의 값으로 생성되며, 데이터의 순서와 무결성을 유지하는 데 사용
- 바이트 단위 증가
- 순서 번호는 송신된 데이터의 각 바이트에 고유하게 지정됨
- 순서 번호가 1000이고 데이터 길이가 500바이트라면 1000~1499를 의미
- 초기 순서 번호 + 송신한 바이트 수
- 확인 응답 번호
- 순서 번호에 대한 응답
- 다음 보내줘야할 데이터의 순서 번호를 의미
- 일반적으로 수신한 순서 번호 + 1로 응답
TCP 연결 수립과 종료
TCP의 연결 과정은 쓰리 웨이 핸드셰이크를 통해 이루어집니다.
세 가지의 과정을 통해 연결합니다.
액티브 오픈 :
연결을 처음 요청하는 측의 동작을 액티브 오픈, 주로 클라이언트에 의해 수행된다.
패시브 오픈:
연결 요청을 받고 나서 요청에 따라 연결을 수립해 주는 호스트, 주로 서버
연결 수립
Step 1 : 클라이언트 -> 서버 (SYN)
- 클라이언트는 연결을 시작하기 위해 SYN 플래그가 설정된 TCP 세그먼트를 보낸다.
- 클라이언트의 ISN 정보도 포함된다.
Step 2 : 서버 -> 클라이언트 (SYN + ACK)
- 서버는 클라이언트의 세그먼트를 받고, 응답으로 SYN 플래그와 ACK 플래그가 설정된 세그먼트를 보낸다.
- 서버의 ISN이 포함된다.
- 동시에, 서버는 클라이언트의 ISN에 대한 확인응답을 보낸다. ISN + 1
Step 3 : 클라이언트 -> 서버 (ACK)
- 클라이언트는 서버의 ISN을 받은뒤, 이를 확인하는 ACK 패킷을 보낸다.
- 확인 응답 번호 = 서버의 ISN +1
여기서 나는 한가지의 의문이 들었다. 클라이언트와 서버와 연결은 하고 싶은데 주고받을 데이터가 없어도 ISN이 필요할까?
결론을 말하자면 필요하다.
초기에 클라이언트에게 보낼 데이터가 없더라도, 나중에 데이터를 보낼 가능에 대비하여 ISN을 설정한다.
연결 종료
액티브 클로즈 :
먼저 연결을 종료하려는 호스트에 의해 수행
패시브 클로즈 :
연결 종료 요청을 받아들이는 호스트에 의해 수행
Step 1 : 클라언트 -> 서버 (FIN)
- 클라이언트는 연결을 종료하기 위해 FIN 플래그가 설정된 TCP 세그먼트를 전송
- 클라이언트는 자신의 마지막 시퀸스 번호를 사용한다.
Step 2 : 서버 -> 클라이언트 (ACK)
- 서버는 클라이언트의 FIN 세그먼트를 받고, 이를 확인하는 ACK 세그먼트를 보낸다.
- 지금도 여전히 서버는 데이터를 보낼 수 있는 상태.
- 클라이언트의 FIN 시퀸스 번호 +1
Step 3 : 서버 -> 클라이언트 (FIN)
- 연결 종료를 위해 FIN 플래그가 설정된 TCP 세그먼트를 클라이언트로 보낸다.
- 클라이언트의 FIN 시퀸스 번호 +1
Step 4 : 클라이언트 -> 서버 (ACK)
- 클라이언트는 서버의 FIN 세그먼트를 받고, 이를 확인 하는 ACK 세그먼트를 보낸다.
- 이후 클라이언트와 서버는 연결을 닫는다.
- 서버의 FIN 시퀸스 번호 +1
TCP 상태
TCP는 연결형 통신과 신뢰할 수 있는 통신을 유지하기 위해 다양한 '상태'를 사용한다.
상태는 어떤 통신 과정에 대한 정보
연결이 수립되지 않는 상태 (Closed, Listen)
- Closed : 아무런 연결이 없는상태
- Listen : 패시브 오픈 호스트는 Listen상태를 유지. 연결을 위한 SYN 세그먼트를 기다리는 상태
연결 수립 상태(SYN-SENT, SYN-RECEIVED, ESTABLISHED)
- SYN-SENT : 액티브 오픈 호스트(클라이언트)가 SYN 세그먼트를 보낸 뒤 그에 대한 응답인 SYN+ACK를 기다리는 상태
- SYN-RECEIVED : 패시브 오픈 호스트(서버)가 SYN세그먼트를 받고 SYN+ACK를 보낸뒤 그에 대한 ACK를 기다린 상태
- ESTABLISHED : 연결이 확립되어 데이터 송수신이 가능한 상태입니다.
- 클라이언트가 서버로부터 SYN+ACK를 받으면 즉시 ESTABLISHED 상태로 전환되지 않습니다.
- 클라이언트는 ACK를 서버로 보내고 나서야 ESTABLISHED 상태로 진입합니다
연결 종료 상태
- FIN-WAIT-1 : 연결 종료의 첫 단계. 앤티브 클로즈 호스트가 FIN 연결 종료 요청을 보낸 상태.
- CLOSE-WAIT : 종료 요청인 FIN을 받은 패시브 클로즈 호스트가 그에 대한 ACK를 보낸 후 대기 상태
- FIN-WAIT-2 : FIN-WAIT-1 이후 ACK를 받은 상태, 상대 호스트의 FIN을 기다리는 상태
- LAST-ACK : CLOSE-WAIT 상태에서 FIN을 보낸후 ACK를 기다리는 상태
- TIME-WAIT : 액티브 클로즈 호스트가 FIN 세그먼트를 수신한 뒤, 이에 대한 ACK 세그먼트를 전송한뒤 보낸 상태
- 패시브 클로즈 호스트는 ACK를 수신하면 바로 CLOSED 상태로 전이
- 액티브 클로즈 호스트는 일정 시간을 기다린뒤 전이
CLOSING 상태 :
보통 동시에 연결을 종료하려 할때 전이 되는 상태. 서로가 FIN을 보내고 받은뒤 각자 그에 대한 ACK 세그먼트를 보냈지만, 아직 자신의 FIN 세그먼트에 대한 ACK를 받지 못한 상태. 즉, 양쪽 모드가 연결 종료를 요청하고 서로의 종료 응답을 기다리는 상태.
ACK 세그먼트를 수신한다면 TIME-WAIT로 상태로 넘어감
UDP 데이터 그램 구조
UDP는 TCP와 달리 비연결형 통신을 수행하는 신뢰할 수 없는 프로토콜이다.
또한 상태를 유지 하지않습니다. 스테이트리스 프로토콜의 일종이라고 불립니다.
- 비연결형 통신
- 스테이트리스 프로토콜
- 신뢰성이 없는 프로토콜
- 속도 우선
UDP VS IP
UDP는 IP 위에서 동작하며, 포트 번호를 통해 애플리케이션 간 데이터를 주고받습니다.
IP는 장치 간 패킷 전달을 담당하며, UDP는 IP의 기본 기능 위에 애플리케이션 식별과 간단한 데이터 전송 기능을 추가합니다.
데이터 그램 :
패킷의 특정한 유형으로, 비연결형 프로토콜(예: IP, UDP)에서 사용되는 데이터 단위
TCP의 오류,흐름,혼잡제어
오류 제어 : 재전송 기법
TCP 세그먼트에 오류 검출을 위한 체크섬 필드가 있지만, 이것으로 신뢰성을 보장하기엔 부족하다.
체크섬은 세그먼트의 훼손 여부만 나타낼뿐, 오류가 있다면 해당 패킷을 읽지않고 폐기하기 때문.
결국, 송신호스트는 세그먼트 전송 과정에 문제가 있다는 것을 인지할 수 없다.
TCP가 어떤 상황에서 송신한 세그먼트가 문제있음을 알아야하는데, 오류를 검출하고 재전송하는 상황은 크게 두가지가 존재합니다.
1. 중복된 ACK를 수신했을때
중복된 ACK를 수신했을때는 다음과 같습니다.
수신 호스트 측이 받은 세그먼트의 순서 번호중에 일부가 누락되었다면 중복된 ACK의 세그먼트를 전송합니다.
RTT(Round Trip Time)
메시지를 전송한뒤 그에 대한 답변을 받기까지 걸리는 시간
2. 타임아웃이 발생
TCP 세그먼트를 송신하는 호스트는 모두 재전송 타이머라는 값을 유지합니다.
호스트가 세그먼트를 전송할 때마다 재전송 타이머를 시작하는데, 이 타이머의 카운트 다운이 끝난 상황을 타임아웃 이라고 합니다.
타임아웃이 발생할때까지 응답을 받지 못하면 재전송을 합니다.
ARQ : 재전송 기법
수신 호스트의 ACK과 타임아웃 발생을 토대로 문제를 진단하고, 문제를 생긴 메시지를 재전송함으로써 신뢰성을 확보하는 방식을 ARQ 라고합니다.
ARQ는 대표적으로 3가지의 방식이 존재합니다.
Stop-and-Wait ARQ
가장 단순한 방식입니다. 제대로 전달했음을 확인하기 전까지는 새로운 메시지를 받지 않는 방식입니다.
즉 메시지를 보내고 ACK를 받지 않으면 기다립니다. 그렇기에, 더 많은 데이터를 받을 수 있음에도 항상 확인 응답을 받아야하기에 성능이 저하됩니다.
GO-BACK-N ARQ
앞서 말한 문제점을 해결하기 위해서는 ACK가 오기전 계속 여러 세그먼트를 보낼 수 있어야합니다.
연속해서 메시지를 보내는 기술을 파이프라이닝 이라고합니다.
파이라이닝 방식을 활용해 여러 세그먼트를 전송하고, 도중에 잘못 전송된 세그먼트가 발생할 경우 해당 세그먼트부터 전부 다시 전송합니다. 순서 번호 n까지의 확인 응답이라고 볼수 있어 누적 확인 응답이라고도 합니다.
Selective Repeat ARQ
선택적으로 재전송하는 방법입니다. 수신측에서 제대로 전송된 각각의 패킷들에 대해 ACK 세그먼트를 보내는 방식입니다.
개별 확인 응답이라고 생각하면됩니다. 올바르게 수신받지 못한 ACK세그먼트가 있다면 그 번호에 대한 세그먼트를 전송합니다.
흐름제어 : 슬라이딩 윈도우
파이프라이닝 기반의 ARQ가 정상적으로 동작하기 위해서는 반드시 흐름제어를 고려해야합니다.
호스트가 한 번에 받아서 처리할 수 있는 세그먼트의 양에는 한계가 있기 때문입니다.
수신 버퍼 : 수신된 세그먼트가 애플리케이션 프로세스에 의해 읽히기 전에 임시로 저장되는 공간
버퍼가 넘치는 상황을 버퍼 오버플로 라고한다.
흐름제어는 이러한 문제 상황을 방지하고자 송수신 속도를 균일하게 유지하는 것을 의미.
MSS: 한 세그먼트에 담을 수 있는 데이터의 최대 크기.
윈도우: 한 번에 송수신 가능한 데이터의 총량.
혼잡 제어
네트워크 혼잡은 너무 많은 데이터가 동시에 네트워크로 전송될 때, 네트워크 장치(예: 라우터)나 링크가 과부하 상태에 도달하면서 데이터 손실이나 전송 지연이 발생하는 상황을 말합니다. TCP는 혼잡 제어를 통해 네트워크 상태를 동적으로 감지하고 데이터 전송 속도를 조절합니다.
흐름제어의 주체가 수신호스트라면 혼잡제어의 주체는 송신호스트이다.
혼잡 윈도우 : 혼잡 없이 전송할 수 있을 법한 데이터의 양
최적의 혼잡제어를 위해 사용하는 방법을 혼잡 제어 알고리즘이라고 부른다.
AIMD
혼잡제어의 기본적인 알고리즘이며, 합으로증가 곱으로 감소. 혼잡이 감지되지 않다면 KTT를 1 선형적 증가,
혼합이 감지되면 혼잡윈도우를 반으로 떨어뜨리는 동작.
이를 정교하게 만드는 혼합 제어 알고리즘이 대표적인 3가지는 다음과 같습니다.
1. 느린 시작 알고리즘
혼잡 윈도우를 1부터 시작해 문제없이 수신된 ACK 세그먼트 하나당 1씩 증가시키는 방식.
결과적으로 RTT의 두배로 지수적으로 증가. 느린 시작 알고리즘을 사용할 때는 느린 시작 임계치라는 값이 있습니다.
혼잡 윈도우 값이 계속 증가하다가 임계치가 되거나, 타임 아웃이 발생하거나, 중복된 ACK 3번이 발생한다면 다음중 세가지의 방법중 하나를 선택합니다.
- 타임아웃 발생 : 혼잡 윈도우 값을 1로, 느린 시작 임계치를 혼잡이 감지되었을 시점의 절반으로 초기한뒤 느린시작 재개
- 혼잡 윈도우 >= 느린 시작 임계치 : 느린 시작 종료, 혼잡 윈도우를 절반으로 초가화한 뒤 혼잡 회피 수행
- 세번의 중복 ACK : 빠른 회복 수행
2. 혼잡 회피 알고리즘
RTT마다 혼잡 윈도우를 1MSS씩 증가시키는 알고리즘.
혼잡 윈도우 크기를 선형적으로 증가시킨다.
이떄, 혼잡 회피 도중 타임아웃이 발생하면 혼잡 윈도우 값은 1로, 느린 시작 임계치는 혼잡이 감지된 시점의 값의 절반으로 초기화 한다음 느린 시작을 수행합니다.
혼잡 회피 도중 세번의 중복 ACK가 발생되었을 때는 혼잡 윈도우 값과 느린 시작 임계치를 대략 절반으로 떨어뜨린 뒤 빠른 회복 알고리즘을 수행합니다.
3. 빠른 회복 알고리즘
세번의 중복된 ACK 세그먼트를 수신하면 빠른 재전송과 더불어 빠른 회복 알고리즘이 수행됩니다.
빠른 회복 알고리즘은 느린 시작은 건너뛰고 혼잡 회피를 수행하는 작업으로 이름처럼 빠르게 전송률을 회복하기 위한 알고리즘.
단, 빠른 회복 도중이라도 타임아웃이 발생하면 혼잡 윈도우 크기는 1로, 느린 시작 임계치는 혼잡이 감지된 시점의 절반으로 떨어뜨린 후 다시 느린 시작을 수행합니다.
ECN : 명시적 혼잡 알림
네트워크에서 혼잡을 감지했을 때, 데이터 손실 없이 혼잡 정보를 송신 측과 수신 측에 알리는 메커니즘입니다.
ECN은 네트워크 중간 장치(예: 라우터)가 혼잡 상태를 감지하면, 데이터를 드롭하지 않고 혼잡 상태를 알리는 플래그를 설정하여 송신 측과 수신 측이 이를 처리할 수 있도록 합니다
ECN 동작 과정
- ECN 협상:
- 연결 설정 시(TCP Three-Way Handshake) 송신 측과 수신 측이 ECN 지원 여부를 협상합니다.
- TCP 헤더의 ECN-Echo(ECE) 및 Congestion Window Reduced(CWR) 비트를 사용합니다.
- 혼잡 감지:
- 네트워크 중간 장치(예: 라우터)가 혼잡을 감지하면, IP 헤더의 ECN 필드를 수정하여 혼잡 상태(1)를 표시합니다.
- 혼잡 알림:
- 수신 측은 TCP 헤더의 ECE 비트를 설정하여 송신 측에 혼잡 상태를 알립니다.
- 혼잡 반응:
- 송신 측은 TCP 헤더의 CWR 비트를 설정하여 혼잡 상태를 수신했음을 확인하고 혼잡 윈도우 크기(CWND)를 줄입니다.
출처 :
https://product.kyobobook.co.kr/detail/S000212911507
혼자 공부하는 네트워크 | 강민철 - 교보문고
혼자 공부하는 네트워크 | 혼자 해도 충분하다! 1:1 과외하듯 배우는 네트워크 자습서『혼자 공부하는 네트워크』는 개발자의 필수 지식인 네트워크를 기본부터 제대로 학습할 수 있도록 돕는
product.kyobobook.co.kr
'CS > Network' 카테고리의 다른 글
[네트워크] 네트워크 계층 (0) | 2025.01.16 |
---|---|
[네트워크] 이더넷 과 통신매체 장비 (0) | 2025.01.14 |
[네트워크] 네트워크 시작하기 (1) | 2024.11.10 |