목차
1. TCP/IP network stack 간단 소개 및 정리
2. Ack Sending Mode 란?
3. Delayed Ack & Quick Ack 소개, 차이점
4. Linux 코드에서는 어떻게 구현이 되어있는가? 코드 분석
5. 관련 RFC
이번에 공부하며 알게된 리눅스 커널의 Ack Sending Mode에 대해서 정리도 할겸, 이렇게 블로그 포스트를 남겨봅니다.
TCP/IP Network Stack에서의 ACK
TCP 통신에서는 "신뢰성"을 가장 최우선에 두고 통신을 합니다. 때문에 UDP같은 프로토콜과는 달리 패킷이 수신자(받는이)에게 잘 도착하였는지, 또는 중간에 유실은 되지 않았는지 확인하는 기능과 옵션들이 있는데요, 이중의 대표적인 기능중 하나가 바로 "Ack 에 기반한 통신"입니다. TCP에서는 수신자에게 보낸 payload data(데이터)에 대한 Ack(Acknowledgement)을 받아야 정상적으로 데이터가 수신자에게 도착을 하였다고 판단합니다. 만약 Ack 이 돌아오지 않는다면 송신자(보낸이)는 수신자가 해당 payload data를 받지 못했다고 판단하고 retransmit(재전송)을 합니다.
때문에 TCP 프로토콜에서는 ACK이 굉장이 중요한 역할을 해주고 있으며, 안정적인 통신을 할 수 있도록 도와주는 기능입니다. 초창기 TCP의 경우, 수신자는 받은 payload data에 대해서 모두 Ack을 보냈었습니다. 그 당시에는 end-point 장비들도 많지 않았고, 유저수도 적었기에 별 문제없이 가능했었지요. 하지만 지금의 네트워크 현황을 본다면, 수신자가 받은 payload data마다 Ack 패킷을 보낸다면, 한정된 대역폭(bandwidth) 자원을 많이 사용하게 되어서 데이터를 보내고 받는데 더 오랜 시간이 걸리게 됩니다. 그리고 이 문제를 해결하고자 나온 기능이 바로 Delayed Ack 입니다.
Ack Sending Mode란?
Ack Sending 이라는 단어가 굉장히 생소하실 수 있는데, 사실 이건 제가 그냥 붙인 용어입니다. 따로 기술용어가 존재하는지는 모르겠지만, 제가 따로 존재 할 수도 있는 그 용어를 찾기 전까지 이 포스트에서는 Ack Sending은 말 그대로 TCP에서의 Ack을 보내는 방식을 일컫는 용어입니다.
Delayed Ack & Quick Ack
Delayed Ack은 사실 널리 알려져있습니다. RFC 문서에도 명확한 수식은 없으나, Delayed Ack 관련 내용이 나와있고, 대부분의 운영체제에서 Delayed Ack을 채택하여 쓰고있습니다. 얼마나 "Delay"를 주는지는 운영체제별로, 또 커널별로 다르지만, 확실한건 받은 payload마다 ack을 보내는 방식보다는 많이 선호되어서 사용되고 있다는 점입니다.
Delayed Ack은 timer에 기반하여 동작합니다. delayed ack timer를 사용하는데, payload를 받은 이후에 timer가 돌기 시작하고 expire, 즉 timeout이 되면 server쪽에 그동안 받은 payload들에 대한 ack을 보내주는 것 입니다. 코드에 따라서 timer 기반이 아닌, 받은 payload 패킷 기반으로도 delayed ack을 구현 할 수도 있습니다. 한 예로, "10개의 payload data를 받으면 ack을 보낸다"가 있습니다.
Quick Ack의 경우 많이 알려지지 않았고, 생각보다 기술문서도 찾기가 힘듭니다. RFC에는 당연히 나와있지 않고요 (Quick Ack이 아닌 다른이름으로는 있을 수 있겠네요). 오래전의 TCP에서 사용되었던 방식이고, 현대에는 대역폭 자원을 많이 낭비한다는 이유때문에 잘 쓰이지 않습니다. 하지만, 1:1 즉각대응 ack을 보낸다면, window size를 빠르게 업데이트 할 수 있다는 장점이 있습니다.
TCP에서 처음 연결을 시도 할 때, 3 way handshaking을 한 후에는 window size를 보고 패킷을 조금씩 보냅니다. 혼잡제어 측면에서 보았을때는 Slow-start 구간으로 볼 수 있습니다. 점차적으로 보내는 패킷을 늘리는 구간인데요, 만약 이 구간에서 Quick Ack을 사용하여 1:1로 ack을 보내면 빠르게 window size를 키운상태에서 통신을 할 수 있습니다. 이는 속도측면에서 큰 향상이 될 수 있습니다.
Linux Kernel 코드의 Ack Sending은?
to-be-added
관련 RFC 문서
RFC 1122 - Requirements for Internet Hosts - Communication Layers