제임스딘딘의
Tech & Life

개발자의 기록 노트/Network Technology

TCP Flags: PSH 그리고 URG

제임스-딘딘 2017. 9. 29. 00:34

개요

TCP헤더를 들여다 보면, 1비트 짜리 플래그가 몇개 있다. 1비트로는 0 아니면 1 만을 나타낼 수 있기 때문에, 플래그는 태생적으로 boolean type 이다.
이 플래그들은 TCP연결을 통하는 데이터의 흐름을 조절 및 제어 하기 위해 사용된다고 알려져 있다.

RFC 3168 에 의해 혼잡 통지(Congestion Notification)을 위해 추가된 CWR 그리고 ECE 플래그를 제외하고나면, 총 6개의 TCP 제어 플래그가 남는다.
일단 CWR과 ECE는 논외로 하자.

TCP 기본 헤더 포맷


Data Offset 다음을 보면, 6개의 플래그, URG, ACK, PSH, RST, SYN, FIN 이 보인다.

그 중, 아래 4개는 TCP연결의 설정(establish), 유지 관리(management) 및 분리(tear-down)를 제어하는 용도이다. 아마  패킷 분석좀 해본 경험이 있다면 이미 익숙 한 플래그 일 것이다.


  • SYN - 연결을 시작한다
  • ACK - 수신 된 데이터를 확인한다
  • FIN - 연결을 닫는다
  • RST - 오류에 대한 응답으로 연결을 중단한다


나머지 두개의 플래그 PSH (Push)와 URG (Urgent)가 있는데, 이 둘의 역할이 종종 헷갈린다.

눈치 챘는가? 이 두개 플래그의 역할, 그것이 바로 오늘 쓸 포스팅의 주제다.



PSH 플래그

PSH 플래그의 기능을 이해하려면 우선 TCP가 데이터를 버퍼링하는 방법을 이해해야 한다. 


기본적인 이야기 부터 해보자. TCP는 OSI Layer 4에서 동작한다. 그것은 패킷 기반 통신의 복잡성을 감추고, 들어온 데이터를 읽어내거나, 혹은, 내보낼 데이터를 쓸 수 있는 간단한 소켓 인터페이스를 상위 Layer에 제공한다. 그리고 TCP는 응용 프로그램(OSI Layer 7)이 언제든지 이 소켓으로부터 읽거나 쓸 수 있도록 버퍼를 제공한다. 버퍼는 TCP 연결 양쪽(송신자와 수신자)의 들어오고 나가는 양쪽 방향 모두에서 구현된다. 말이 헷갈린다면 간단히 생각하자. 송신자의 TCP도 read buffer, write buffer 를 가지고, 수신자의 TCP도 read buffer, write buffer를 가진다.


아래 다이어그램은 송신 전에 송신자가 데이터를 버퍼링하는 방법과 수신자가 수신 시 데이터를 버퍼링하는 방법을 보여준다.





MSS (Maximum Segment Size)를 초과하는 데이터 보낼때를 상상해 보라. 예를 들면 큰 파일 전송 같은 것 말이다. 버퍼는 이런 큰 데이터를 보다 효율적으로 전송할 수 있게 해주는 역할을 한다. 그러나 데이터를 가능한 한 빨리 전송해야 하는 실시간 응용 프로그램을 처리 할 때는 큰 버퍼가 좋지 않다. 예를 들어 TCP가 패킷을 보내기 전에 패킷의 버퍼를 데이터가 가득 채울때까지 기다리다가 전송한다면.. 텔넷 세션에 어떤 일이 발생하는지 생각해보라. 첫 번째 패킷이 원격 장치로 전송되게 하려면 그 전에 먼저 문자 타이핑을 1000자 넘게 해야할 것이다. 이럴땐 별로 유용해 보이지 않는다. 


만약 텔넷의 예가 어렵다면, 카카오톡이나 채팅 프로그램 같은걸 상상해 보면 된다. 짧은 메세지 몇글자 보내려 하는데, TCP버퍼가 가득 찰때까지 기다렸다가 전달된다면? 답답할 것이다.


바로 이것이 PSH 플래그가 필요한 경우다.

응용프로그램(Application Layer) 에서는 소켓에  "Push"하는 옵션을 사용하여 데이터를 쓸 수있다. 이 옵션은  추가 데이터가 버퍼에 들어갈 때까지 기다리지 않고 즉시 데이터를 내보낸다. 이 경우 송신 TCP 패킷의 PSH 플래그가 1로 설정된다. 연결의 반대편인 '수신측' 종단에서는 PSH 플래그가 설정된 패킷을 수신하면 TCP세그먼트를 응용프로그램에 즉시 전달하도록 동작한다. PSH 플래그가 없다면 수신측에서도 버퍼에 일정량의 데이터가 모일때까지 기다렸다가 응용프로그램에 전달할 것이다.


설명이 어렵고 이해가 안된다면 아래 요약만 일단 기억하자

TCP의 push 기능은 다음 두 가지를 수행한다.

  • 송신측에서의 PSH 기능: 호스트의 응용프로그램(Application Layer)은 '이 데이터는 버퍼에 쌓지 말고 즉시 보내라' 고 TCP Layer에 알리는 역할을 한다.
  • 수신측에서의 PSH 기능: '이 데이터는 버퍼에 쌓지 말고 즉시 응용프로그램(Application Layer) 에 올려야 되겠군' 하고 수신측 호스트의 TCP Layer가 인식하게 하는 역할을 한다.


아래 패킷 캡쳐 예를 보자.

패킷 #36은 HTTP GET 요청인데, PSH 플래그를 사용하는 예를 볼 수 있다. 이 HTTP 요청에는 PSH 플래그가 설정되어 클라이언트에 추가 할 데이터가 더 이상 없고 요청이 애플리케이션 (이 경우 웹서버 데몬)에 즉시 전송되어야 함을 나타낸다. 다시 말하면, PSH 플래그는 송신기가 더 이상 송신 할 데이터가 없다는 것을 수신기에 알리기 위해 사용된다 (현재로서는).



HTTP.cap





앞서 언급 했듯이, PSH 플래그는 TCP를 통한 실시간 통신을 용이하게하기 위해 사용된다. 관심이 있다면 한가지 실험을 해보면 좋을것 같다. 텔넷의 패킷을 캡쳐해서 wireshark로 살펴보길 바란다. 텔넷 세션의 패킷 캡처는 텔넷 데이터를 전송하는 모든 패킷이 키 누름이 TCP에 의해 버퍼링되는 것을 방지하기 위해 PSH 플래그를 1로 설정되어 있음을 보여줄 것이다.



URG 플래그

URG 플래그는 이름 그대로 긴급(Urgent) 하다는 의미를 표시한다. 이 플래그는 수신측에게 '네가 현재 받은 TCP 세그먼트에 포함된 데이터는 긴급한 데이터야. 우선 처리되도록 우선순위를 높게 주길 바래' 쯤의 의미를 알리는 역할이다. 이때, 수신측 호스트의 TCP stack은 TCP 헤더의 16비트 필드인 'Urgent Pointer'를 측정하게 된다. Urgent Pointer는 '긴급한 정도'를 나타낸다. 얼마나 긴급한지 말이다.





URG 플래그는 현대의 프로토콜에서는 많이 사용되지 않는다. 왜냐하면 이 플래그의 사용이 더이상 추천되지 않기(RFC 6093) 때문이다. 아주 휘귀하다. 그러나 운 좋게도 이전에 언급 했던 텔넷의 패킷 캡처에서 URG 플래그의 예를 볼 수 있다. 


cm4116_telnet.cap





수신측 입장에서 패킷 #86에서 전송 된 0xFF 문자는 패킷 #70 의 텔넷 명령 0xF2 (242)보다 앞서서 전달된다. RFC 854[각주:1]에 따라, 이 명령은 TCP URG 플래그가 설정된 상태로 보내야한다. 패킷 #86의 긴급 포인터는 세그먼트의 첫 번째 바이트 (이 경우 전체 세그먼트)가 긴급 데이터로 간주되어야 함을 나타낸다.


이것은 URG 플래그의 가장 훌륭한 예는 아니겠지만, 현실에서의 여러 캡처를 아무리 살펴봐도 실제 사용되는 다른 예를 거의 찾아볼 수가 없었다.


TCP의 PSH 및 URG 기능에 대한 더욱 자세한 내용은 온라인 TCP/IP 가이드를 참조하길 바란다.


  1. RFC 854는 TELNET PROTOCOL SPECIFICATION 에 대한 내용이다. 다음 주소에서 확인할 수 있다. https://tools.ietf.org/html/rfc854 [본문으로]

'개발자의 기록 노트 > Network Technology' 카테고리의 다른 글

TCP : BBRv2 및 CUBIC 의 공존  (0) 2024.02.16
무선 LAN, Wi-Fi 이야기  (0) 2017.02.08