소켓 경로 길이가 100 자로 제한되는 이유는 무엇입니까?


18

유닉스 시스템에서 경로 이름은 일반적으로 길이 제한이 없습니다 (Linux에서는 4096 문자) ... 소켓 파일 경로는 약 100 문자 ( Linux에서는 107 문자 ) 로 제한됩니다 .

  • 첫 번째 질문 : 왜 그렇게 낮은 제한이 있습니까?

나는 현재 작업 디렉토리를 변경하고 여러 소켓은 모두 같은 경로를 사용하여 파일을 여러 디렉토리에 생성하여이 제한을 해결할 수 보인다 확인했습니다 ./myfile.sock클라이언트 응용 프로그램이 제대로 예상 서버 프로세스에 짝수하지만 연결하는 것 : lsof쇼 모든 그들 중 동일한 소켓 파일 경로에서 수신 대기합니다.

  • 이 해결 방법이 신뢰할 수 있습니까 아니면 제가 운이 좋습니까?
  • 이 동작이 Linux에만 해당됩니까? 아니면이 해결 방법이 다른 Unix에도 적용될 수 있습니까?

현재 OpenBSD 시스템 또는 Mac OS X 10.11에서는 제한이 훨씬 낮습니다 (104).
thrig

중요한 것은, 그것은 :) 호환성을 위해, (108)보다 낮은한다는 것이다

AFAIK Linux에서는 108 자입니다. 컴퓨터에서 /usr/include/$arch-linux-gnu/sys/un.h를 확인하십시오.
schaiba

@ schaiba : 108 바이트. 이는 null 종결 자로 끝나는 107 문자 문자열을 의미합니다.
WhiteWinterWolf

답변:


18

사용하는 동안 다른 플랫폼, 또는 그 이상 물건과의 호환성과의 호환성 오버런을 피하기 위해 snprintf()하고 strncpy().

Michael Kerrisk 는 1165 페이지 57 장, 소켓 : Unix 도메인의 에서 설명 합니다.

SUSv3은 sun_path 필드의 크기를 지정하지 않습니다. 초기 BSD 구현은 108 및 104 바이트를 사용했으며 현대의 한 구현 (HP-UX 11)은 92 바이트를 사용합니다. 이식 가능한 응용 프로그램은이 낮은 값으로 코딩해야하며이 필드에 쓸 때 버퍼 오버런을 피하려면 snprintf () 또는 strncpy ()를 사용해야합니다.

일부 소켓의 길이는 110 자이므로 Docker 녀석은 그것을 재미있게 만들었습니다.

이것이 LINUX가 108 문자 소켓을 사용하는 이유입니다. 이것이 변경 될 수 있습니까? 물론이야. 이것이 바로 이전 운영 체제에서이 제한이 발생한 이유입니다.

답을 인용 :

편리한 커널 데이터 구조에서 사용 가능한 공간과 일치해야했습니다.

McKusick 등의 "4.4BSD 운영 체제의 설계 및 구현"인용 알. (369 페이지) :

메모리 관리 기능은 mbuf라고하는 데이터 구조를 중심으로 이루어집니다. Mbufs 또는 메모리 버퍼의 길이는 128 바이트이며이 공간의 100 또는 108 바이트는 데이터 저장 용으로 예약되어 있습니다.

다른 OS (유닉스 도메인 소켓) :


1
SUSv3 XNET은이 문제에 대한 합의가 없기 때문에 조용했습니다.
fpmurphy

당신의 관점을 증명할 수있는 링크가 있습니까?

이 답변에 감사드립니다. 그것은 (예를 들어,라는 이름의 소켓 파일을 만들고 다른 작업 디렉토리를 기준으로 동일한 이름 베어링 여러 소켓 파일을 사용하여 믿을 수 ./my.socket디렉토리 아래에 A/명명 된, 또 다른 소켓 파일 ./my.socket디렉토리 아래를 B/)? lsof두 소켓 파일을 구별하지 않지만 여전히 작동하는 것처럼 보이지만 이것이 운이 좋기 때문에 궁금합니다. 이것은 이미 허용 된 크기보다 긴 경로 아래에 소켓 파일을 작성하는 좋은 해결책입니다.
WhiteWinterWolf

내 메일 서버에서 유닉스 소켓을 검색 할 때 전체 경로 이름을 가져 오는 것 같습니다 : lsof -U| grep amavis(newline)amavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock

그렇습니다. 내가 테스트 한 결과 상대 이름은 작동하지만 여전히 이상하게 보입니다 ...하지만 작동합니다. 내 응용 프로그램은 시스템 전체가 아니기 때문에 소켓 파일은 다른 모든 응용 프로그램 데이터와 함께 사용자 제어 위치에 저장 /tmp됩니다. 단일 소켓 파일을 포함합니다 (완전히 추악하지만 휴대용 및 보안).
WhiteWinterWolf 19:38에

5

그 이유에 관해서, nwildner는 이미 훌륭한 답변을 썼습니다 .

여기서는 방법과 상대 경로 사용법에 중점을 둘 것입니다.

내부적으로 소켓 파일은 이름으로 조회 할 수 있지만 일반적으로 inode에서 조회합니다. Linux에서이 조회는 net / unix / af_unix.c에unix_find_socket_byinode() 정의 된 기능으로 보장됩니다 .

다음과 같이 쉽게 확인할 수 있습니다.

  • 두 개의 디렉토리 A /B /를 작성하십시오 .
  • 각 디렉토리에서 프로세스가 동일한 이름을 가진 소켓 파일에서 청취하도록하십시오. 다음과 socat같은 명령을 사용합니다.
$ socat UNIX-LISTEN:./my.sock -
  • 이제 A / my.sockB /로 또는 그 반대로 이동하여 소켓 파일을 교환하십시오 .
  • 이제부터 클라이언트 응용 프로그램이 A / my.sock에 연결 되면 서버 B 에 연결되고 B / my.sock에 연결 되면 서버 A에 연결됩니다 (통신이 끝나면 서버 프로세스가 진행될 수 있음에 유의하십시오) 자체 소켓 파일이라고 생각되는 것을 합법적으로 삭제하십시오).

소수의 유닉스 시스템 (Linux Debian, FreeBSD 및 OpenIndiana에서 다양성을 얻음) 에서이 동작을 확인 했으므로이 동작은 표준이 아닌 경우 적어도 널리 퍼진 것으로 보입니다.

클라이언트 프로세스가 서버와 초기 통신을 설정하는 방법을 알지 못할 수 있으므로 절대 경로는 일반적으로 클라이언트와 서버 프로세스 간의 규칙으로 사용됩니다.

그러나이 초기 통신이 문제가되지 않으면 소켓 파일 작성에 상대 경로를 사용하는 것이 안전 해 보일 수 있으므로 소켓 파일 위치가 서버 프로세스에 의해 직접 제어되지 않을 때 경로 길이 문제를 피할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.