FreeBSD에서 실행되고 TCP를 사용하는 서버 애플리케이션에서 작업하는 동안 내 애플리케이션이 TCP 소켓에서 SO_KEEPALIVE를 명시적으로 비활성화했음에도 불구하고 TCP keepalive 프로브가 전송되는 것을 발견했습니다.
에 따르면RFC1122 섹션 4.2.3.6(TCP 연결 유지):
"연결 유지가 포함된 경우 애플리케이션은 각 TCP 연결에 대해 이를 켜거나 끌 수 있어야 하며 기본적으로 꺼짐으로 설정되어 있어야 합니다."
조정 가능한 매개변수를 찾았습니다.net.inet.tcp.always_keepalive활성화되어 있고(1로 설정) 이를 비활성화하면 연결 유지 프로브가 전송되지 않습니다.
FreeBSD에 이 동작을 포함시키는 이유는 무엇입니까? 내가 알 수 있듯이 Linux와 Windows에는 그러한 옵션이 없지만 FreeBSD와 Mac OS X에는 있으므로 RFC를 위반합니다.
더 구체적으로 말하면 어떤 상황에서 애플리케이션의 희망 사항을 무시하는 것이 합리적입니까?
내 경우에는 옵션을 비활성화할 수 있으므로 이는 간단한 수정이지만 해당 옵션이 왜 존재하는지 알고 싶습니다.
이 질문Linux가 RFC에 따라 동작함을 보여줍니다.
답변1
기본적으로 연결 유지를 켜는 이유는 다음과 같습니다.https://svnweb.freebsd.org/base?view=revision&revision=47752
전역 TCP 연결 유지를 제어하고 기본값으로 켜는 핸들을 추가합니다.
이름에도 불구하고 TCP 세션을 활성 상태로 유지하지 않으며, 다른 쪽 끝이 AWOL되면 해당 세션을 종료합니다. 이는 NAT, 동적 IP 할당을 사용하거나 가동 시간 상한이 2^32 * 10^-3초인 클라이언트에서 자주 발생합니다.
라이브 TCP 연결의 경우 2시간마다 최소 2개의 TCP 패킷이 발생하기 때문에 네트워크 트래픽이 감지할 수 있는 증가는 없습니다.
많은 서버가 이미 연결 유지를 자체적으로 활성화하고 있습니다.
호스트 요구 사항 RFC는 10년이 되었으며 현재 InterNet의 잃어버린 클라이언트에 대해 알지 못합니다.
어쨌든 애플리케이션에서 요청하는 경우(예: C에서) 연결 유지를 끄는 것이 좋습니다.
int val = 0;
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
하지만 이를 고치는 것은 쉽지 않습니다.
답변2
조정 가능한 손잡이가 있어야 한다고 생각하지만 기본적으로 꺼 두는 것이 더 나을 수도 있습니다.
내 추론은 응용 프로그램 개발자가 이러한 종류의 결정을 잘못 내릴 수 있으며 궁극적으로 시스템 관리자가 응용 프로그램 개발자가 아닌 이러한 종류의 네트워크 정책을 제어해야 한다는 것입니다.