본문 바로가기

CS ﹒ Algorithm/(new)Network

TCP/IP (5) 트랜스포트 계층

 

Transport Layer

 

어플리케이션의 식별 및 요구에 맞는 전송 제어를 수행하여 네트워크와 어플리케이션을 연결하는 역할을 담당한다.

네트워크 계층이 패킷을 보내고 받으며 캡슐화를 해제한다면, 어떤 애플리케이션에 전달할지는 트랜스포트 계층에서 결정한다.

포트 번호라는 숫자를 이용해 패킷을 전달할 애플리케이션을 식별하고, 애플리케이션의 요건에 따라 송수신량을 제어하거나 손실된 패킷을 재전송한다.

주로 사용되는 프로토콜은 UDP(User Datagram Protocol) 혹은 TCP(Transmission Control Protocol) 중 하나로, 애플리케이션의 실시간성이 중요할 경우 UDP, 신뢰성을 요구할 경우 TCP를 사용한다.

 

 

 

1. UDP

 

음성 통신(VoIP) 혹은 DHCP, 시각 동기화 등 속도가 중요한 애플리케이션에서 주료 사용한다.

커넥션리스 타입으로 UDP 커넥션이라는 통신로를 만들어 송신하며, 프로토콜 포맷을 간단하게 하고 확인 응답을 생략하여 속도를 향상시키는 것이 주된 목적이다.

 

1-1. UDP 패킷 포맷

 

RFC768로 표준화되었으며 헤더의 프로토콜 번호는 17이다.

실시간성을 중시하여 패킷 포맷이 매우 간단하다. 헤더 필드가 고작 4개 뿐이며, 헤더 길이도 8바이트 밖에 되지 않는다.

데이터그램을 만들고 서버나 상대의 상태를 전혀 신경쓰지 않고 오직 송신하기만 하며, 수신자는 헤더에 포함된 길이와 체크섬을 이용해 검사하고 문제가 없다면 수신한다.

 

(1) Source port / Destination port

애플리케이션(프로세스) 식별에 사용되는 2바이트 값이다.

커넥션을 만들 때 OS가 정한 범위에서 무작위로 할당한 값을 송신지 포트 번호로, 프로세스마다 정의된 값을 수신지 포트번호로 정하고 서버에 전송한다.

데이터그램을 받은 서버는 수신지 포트 번호를 보고 어떤 어플리케이션의 데이터인지 판별해 해당 애플리케이션에 데이터를 전달한다.

 

(2) UDP 데이터그램의 길이

UDP 헤더(8바이트)와 UDP 페이로드(애플리케이션 데이터)를 합친 데이터 그림 전체를 나타내는 2바이트 필드이다.최소값은 UDP 헤더만으로 구성된 경우의 8, 최대값은 MTU에서 IP 헤더의 길이를 뺀 값이다.

 

(3) 체크섬

받아들인 UDP 데이터그램의 정합성을 체크하기 위해 사용하는 2바이트 필드이다.

 

 

1-2. 포트 번호

트랜스포트 계층에서 가장 중요한 필드로, IP 패킷이 특정 단말에 도착시키는 것은 가능하나 해당 패킷이 어떤 어플리케이션에게 도달해야 하는지는 포트 번호로 판단한다.

 

송신지 번호는 돌아올 패킷을 위해 무작위로 주어지며, 수신지는 상대가 받아야할 어플리케이션의 포트 번호가 입력된다.0번에서 65535번까지 있으며 System Ports(well-known ports), User Ports, Dynamic and/or Private Ports로 분류된다.System Ports와 User Ports는 서버 어플리케이션을 식별하는 포트 번호로 수신지 포트 번호에 사용되며, Dynamic and/or Private Ports는 주로 클라이언트 어플리케이션을 식별하는 번호로써 송신지 번호로 사용된다.

 

(1) System Ports

포트번호 0~1023에 해당한다.well-known port로도 불리며, ICANN의 자원 관리 기능인 IANA에 의해 관리되고 서버 어플리케이션에 유일하게 묶여있다.UDP 123의 경우 ntpd, xntpd 등 시각 동기화를 위한 NTP 서버, TCP 80은 Apache 혹은 IIS, nginx 등 웹사이트용 HTTP 서버 어플리케이션이 사용한다.

 

 

(2) User Ports

포트 번호 1024~49151에 해당한다.

IANA에 관리되며 제조사가 개발한 독자 서버 어플리케이션에 묶여있다.

TCP 3306 - Oracle MySQL

TCP 3389 - Microsoft 원격 데스크톱

TCP 8080 - Apache Tomcat

 

(3) Dynamic and/ or Private Ports

포트 번호 49512-65535에 해당한다.

IANA에 의해 관리되지 않고 클라이언트 어플리케이션이 커넥션을 만들 때 송신지 포트 번호로 무작위 할당된다.

무작위 할당 포트 범위는 OS별로 다르다.

 

 

 

 

1-3. UDP 방화벽

송신지/ 수신지 IP 주소 및 트랜스포트 계층의 프로토콜, 송신지/수신지 포트 번호로 커넥션을 식별하고 송신을 제어하는 기기.

규칙에 따라 통신을 식별하고 위협에서 시스템을 보호한다.

해당 제어 기능을 stateful inspection이라고 부르며, 통신/허가 거부를 정의하는 필터링 규칙(filtering rule)과 통신을 관리하는 커넥션 규칙(connection rule)을 사용해 통신을 제어한다.

 

 

(1) filtering rule

허가할 통신과 거부할 통신의 형태를 정의한다.

송신지/수신지 ip 주소, 프로토콜, 송신지/수신지 포트번호, 통신 제어(Action) 등의 설정 항목으로 구성되어 있다.

예를 들어 웹 접근의 경우 HTTP(TCP 80), HTTPS(443), DNS(53)도 허가해야 하나, 특정할 수 없는 요소는 ANY로 설정한다.

송신지도 대개 ANY로 설정한다.

 

(2) connection table

자신을 경유하는 커넥션 정보를 커넥션 테이블로 관리한다.

송신지/수신지 IP주소, 프로토콜, 송신지/수신지 포트 번호, 커넥션 상태, idle timeout 등 각종 요소를 테이블로 관리한다.

 

(3) stateful inspection

- UDP 데이터그램을 받아들여 기존 설정된 필터링 규칙과 조합한다.

- 액션이 accept인 경우 커넥션 테이블에 커넥션 엔트리를 추가하고, 해당 커넥션 엔트리에 대응하는 반환 통신을 허가하는 필터링 규칙을 추가한다. 이후 서버에 UDP 데이터그램을 전송한다.

만약 reject인 경우 커넥션 테이블에 추가하지 않고 클라이언트에 Destination Unreacheable을 반환한다.

ICPM 패킷 액션이 drop인 경우 아무런 행동도 취하지 않고 데이터그램을 파기하여 외부에 어떠한 정보도 응답하지 않는다.

- 액션이 accept인 경우 서버로부터 response가 발생하여, 위에서 만들어진 필터링 엔트리로 허가 제어를 실행하고 전송하며 idletime을 0초로 초기화한다.

- 통신이 끝나면 idletime을 증가시키며 타임 아웃이 경과하면 필터링 엔트리를 삭제한다.

 

 

 

 

 

2. TCP 

 

데이터 전송의 신뢰성을 요구하는 애플리케이션에서 사용한다. (메일, 파일 전송, 웹 브라우저 등)

데이터 송신 전 TCP connection이라는 논리적 통신로를 만들어 통신환경을 정비한다.

TCP 커넥션은 송신 전용의 송신 파이프와 수신 전용의 수신 파이프로 구성되며, 2개의 논리적 파이프를 전이중으로 사용하여 송신 및 수신 패킷을 반복 전달하여 신뢰성이 높다.

 

UDP를 개량한 QUIC(Quic UDP Internet Connections)방식도 있으나 아직은 TCP 방식이 인터넷상 트래픽의 대부분을 차지하고 있다.

 

2-1. TCP 패킷 포맷

 

 

 

(1) Source port/ Destination port

어플리케이션 식별에 사용되는 2바이트 숫자.

 

(2) Sequence number

TCP 세그먼트를 올바른 순서로 재조합하기 위해 사용되는 4바이트 필드.

송신 시 애플리케이션 계층에서 받은 데이터의 각 바이트에 초기 시퀀스 번호(IS, Initial SequenceNumber)에서 연번을 부여하여 수신 측 단말은 받은 번호를 확인해 번호순으로 정렬하고 전달한다.

시퀀스 번호는 3way handshake 때 무작위 값이 초기 시퀀스 값으로 설정되고 tcp 세그먼트를 송신할 때마다 송신한 바이트 수만큼 더해진다.

 

(3) Ack (Acknowledgement number)

받아들인 데이터 시퀀스 번호 + 애플리케이션 데이터 길이가 설정되며, 해당 번호부터 데이터를 전송해달라는 의미로 사용된다.

시퀀스 번호와 ACK 번호를 조합하여 신뢰성을 확보한다.

 

(4) Data offset

TCP 헤더의 길이를 나타내는 4바이트 필드로 어디까지가 헤더인지 식별하는데 사용한다.

 

(5) Control bit

커넥션 상태를 제어하는 필드.

 

(6) Window

받은 데이터 크기를 알리는 2바이트 필드.

확인 응답을 기다리지 않고 받을 수 있는 데이터 크기를 윈도우 크기를 통해 알린다.

최대 65535바이트까지 알릴 수 있으며 0은 받을 수 없음을 알린다.

 

(7) Checksum

TCP 세그먼트의 정합성 체크를 위한 2바이트 필드.

 

(8) Urgent point

컨트롤 비트의 UTH 플래그가 1로 설정되었을 때만 유효한 2바이트 필드로 긴급 데이터가 있을 시 알리는 역할을 한다.

 

(9) Option

TCP 확장 기능을 알리기 위한 4바이트 필드.

 

(10) MSS ? (Maximum Segment Size)

TCP payload의 최대 크기를 의미한다.

MTU는 IP 패킷의 최대 크기이며, MSS는 TCP 세그먼트에 삽입할 수 있는 최대 크기이다.

기본값은 IPv4의 경우 MTU-40바이트, IPv6에서는 MTU-60바이트.

L2 (ethernet) + IPv4(L3) 환경에서 MTU가 1500바이트일 때 MSS는 1460바이트.

핸드세이크 시 지원하는 MSS 값을 미리 알린다.

 

(11) SACK (Selective Acknowledgement)

유실된 TCP 세그먼트를 재전송하는 기능으로 초기에는 모든 TCP를 재전송하는 방식이였으나 SACK를 지원하는 경우 사라진 세그먼트만 재전송할 수 있으며 현재 대부분의 OS에서 지원한다.

 

 

 

2-2. 상태전이

TCP의 신뢰성 확보를 위한 3단계를 의미한다.

 

(1) 접속 시작 단계

 

3way handshake로 커넥션을 연다.

커넥션을 확립하기 전 미리 사전 정보를 교환하는 절차다.

 

서로 지원하는 기능 및 시퀀스 번호를 결정하고 open이라는 준비 작업을 수행하고, 커넥션을 만들어가는 클라이언트의 처리를 active open, 서버의 처리를 passive open이라고 부른다.

 

핸드세이크 시작 전 클라이언트는 CLOSED, 서버는 LISTEN상태이다.

-> 클라이언트가 SYN flag 1, 시퀀스 번호에 무작위 값을 설정한 SYN 패킷을 송신하고 OPEN 상태가 된다. 클라이언트는 SYN-SENT 상태가 되며 SYN/ACK 패킷을 기다린다.

-> 서버는 SYN 패킷을 받고 Passive Open 처리로 들어간다. SYN/ACK 플래그를 각각 1로 설정한 SYN/ACK 패킷을 반환하고 SYN-RECEIVED 상태가 된다. 시퀀스 번호는 무작위이며 확인 응답 번호는 SYN 패킷 시퀀스 번호에 1을 더한 값이다.

-> 클라이언트는 SYN/ACK 패킷을 받고 ACK 플래그를 1로 설정한 ACK 패킷을 반한하고 ESTABLISHED 상태로 이동한다.

-> ACK 패킷을 받은 서버도 ESTABLISHED 상태로 이동한다. 둘 다 ESTABLISHED가 된다면 데이터를 송수신할 수 있게 된다.

 

 

(2) 접속 확립 단계

 

- 흐름 제어

수신 측 단말이 수행하는 흐름의 양 조절로, 윈도우 크기 필드를 사용해 받을 수 있는 데이터 양을 알린다.

송신측은 해당 크기를 바탕으로 ACK 응답 없이도 데이터를 보내며 데이터 유실이 일어나지 않는 선에서 가장 많은 데이터를 송신한다.

이를 슬라이딩 윈도우 방식이라고 한다.

 

- 혼잡 제어

송신측 단말이 수행하는 흐름의 양 조절이다.

TCP는 대량 송신 패킷에 의해 네트워크가 혼잡하지 않도록 Congestion control algorithm을 이용하여 패킷 송신 수를 제어한다.

패킷 송신 수를 혼잡 윈도우(congestion window)라고 한다.

혼잡 제어 알고리즘은 3가지 방식이 있다.

Loss base : 패킷 유실이 발생하면 혼잡을 판단한다.

Latency base : 지연이 발생하면 혼잡을 판단한다.

Hybrid base : 양쪽을 종합적으로 고려한다.

 

- 재전송 제어

패킷 유실이 발생하면 ACK 패킷을 통해 감지하고 재전송한다.

수신측 단말이 계기가 되는 중복 ACK와 송신측 단말이 계기가 되어 수행하는 재전송 타임아웃이 있다.

 

중복 ACK ?

수신측 단말이 받은 TCP 세그먼트 시퀀스 번호가 건너뛰고 전송되면 확인 응답으로 같은 ACK 번호를 연속 송출한다.

송신측 단말은 중복 ACK를 일정 수 이상 받으면 대상 TCP 세그먼트를 재전송한다.

이를 Fast retransmit이라고 부른다.

 

재전송 타임아웃?

TCP 세그먼트 전송 이후 재전송 타이머(retransmission timer)가 끝날 때까지 ACK 패킷을 받지 못하면 재전송 타임아웃에 도달해 재전송 대상이 되는 TCP 세그먼트를 송신한다.

 

 

(3) 접속 종료 단계

4way handshake 과정을 거치며 3way handshake와 달리 어느 쪽이 시작할지 정해져있지 않다.

시작하는 쪽을 Active close, 받는 쪽을 Passive close라고 한다.

 

 

클라이언트는 애플리케이션으로부터 CLOSE 처리 요구가 들어오면 액티브 클로즈 처리를 시작하여 FIN/ACK 패킷을 송신한다. 그리고 서버의 FIN/ACL 패킷을 가진 FIN-WAIT1 상태로 이동한다.

-> FIN/ACK 패킷을 받은 서버는 패시브 클로즈 처리를 시작하며, FIN/ACK 패킷에 대한 ACK 패킷을 송신하고 어플리케이션에 CLOSE 처리를 의뢰한다. 이후 CLOSE_WAIT 상태로 이동한다.

-> ACK를 받은 클라이언트는 FIN/ACK 패킷을 기다리는 FIN-WAIT2 상태로 이동한다.

-> 서버는 어플리케이션으로부터 클로즈 처리 요청을 받으면 FIN/ACK 패킷을 송신하고 송신한 패킷에 대한 ACK 패킷을 기다리는 LAST-ACK 단계로 이동한다.

-> 클라이언트는 받은 FIN/ACK 패킷에 대한 ACK 패킷을 전송하고 TIME-WAIT 상태로 이동한다.

-> 서버는 CLOSED 상태로 이동하고 커넥션을 삭제하며, 커넥션에 확보 중이던 자원을 모두 해제한다.

-> TIME-WAIT에 이동한 클라이언트는 설정된 시간이 지나면 CLOSED 상태로 이동하여 커넥션을 삭제하고 리소스를 모두 해제시킨다.

 

 

 

 

2-3. 옵션 기능

 

(1) TCP Fast Open (TFO)

3way handshake로 애플리케이션 데이터를 교환하는 기능이다.

매번 3way handshake로 지연 시간이 발생하기 때문에, 3way handshake의 SYN, SYN/ACK에 애플리케이션 데이터를 실어 보냄으로 지연 시간을 줄인다.

첫 번째 3way handshake는 기존과 같으며 옵션 필드로 미리 TFO Cookie를 교환한 뒤, 이후 핸드쉐이크마다 TFO를 발동하낟.

 

(2) Nagle 알고리즘

데이터가 크기가 작은 TCP 세그먼트를 모아서 송신하는 기능이다.

MSS보다 작은 TCP 세그먼트를 모아 한 번엔 송신함으로 교환할 세그먼트 수와 패킷 왕복을 줄인다.

 

(3) 지연 ACK

데이터 크기가 작은 TCP 세그먼트에 대한 확인 응답을 늦추는 기능.

MSS를 가득 채우지 않는 TCP 세그먼트에 대한 확인 응답을 일정 개수만큼 늦춰 여러 ACK를 하나로 모아서 반환하여 통신 효율을 높힌다.

지연 ACK는 수신측 단말, Nagle은 송신측 단말이 늦추는 것인데 두 개가 한 번에 동작하면 대기 상태가 일어나 오히려 문제가 될 수 도 있다.

 

(4) Early Retransmit

Fast Retransmit이 활동하지 않는 특정 환경에서 중복의 ACK 임계깞을 낮춰 Fast Retrasnmit을 유발한다.

RFC5827에서 규격화되었다.

Fast Retransmit은 일정 횟수 이상 중복 ACK를 받아야 발동하나 그러면 처리량이 저하된다.

Early Retransmit은 송신하고 싶으나 ACK를 받지 못하는 미처리 TCP 세그먼트가 4개 미만이고 3회 이상의 중복 ACK가 발생하지 않는 TCP 상태에서 중복 ACK 임계값을 미처리 TCP 세그먼트 수까지 낮춰 발동하기 쉽게 한다.

 

(5) Tail Loss Probe (TLP)

전송한 세그먼트 중 마지막 부분이 유실되었을 때 재전송 타임아웃보다 빠르게 재전송을 시도하는 기능.

송신하는 TCP 세그먼트가 적은 가장 마지막 부분 패킷이 유실되어도 중복으로 받을 수 있는 ACK 횟수가 부족해서 Fast Reteansmit이 발생하지 않아 재전송 타임아웃과 별개로 그 보다 짧은 값이 되는 PTO(Prove Timeout)을 정의한다.

데이터를 보낼 때 타이머를 시작하고 PTO에 도달하면 재전송을 시도한다.

 

 

2-4. TCP 방화벽

 

UDP와 큰 차이는 없으나 정보를 나타내는 열이 추가된다.

 

(1) 방화벽은 클라이언트의 Outside 인터페이스로 SYN 패킷을 받아 필터링 규칙과 조합한다.

(2) 액션이 Accept인 경우 커넥션 테이블에 커넥션 엔트리를 추가하고, 대응하는 필터링 규칙도 추가한다.

거부인 경우 커넥션 엔트리를 추가하지 않고 RST 패킷을 반환한다.

DROP인 경우 세그먼트를 파기하고 이외에 동작하지 않는다.

클라이언트는 패킷이 돌아오지 않으면 정해진 간격으로 반복해서 재전송한다.

(3) Accept인 경우 서버로부터 SYN/ACK 패킷을 반환하며, 이와 함께 커넥션 상태에 맞춰 커넥션 엔트리 상태를 SYNC-SENT에서 ESTABILISHED로 변경하고 idletime을 0초로 초기화한다.

(4) 전송이 끝나면 FIN/ACK -> ACK -> FIN/ACK -> ACK 흐름을 확인하고 커넥션 엔트리를 삭제한다.

 

데이터 전송 중 비정상적으로 어플리케이션이 종료되어 정상적으로 클로즈하지 못하는 경우, 불필요한 메모리 낭비를 줄이기 위해 idle timeout되면 엔트리와 필터링 규칙을 삭제하고 자원을 회수한다.