Unix 시스템에서 경로 이름은 일반적으로 사실상 길이 제한이 없습니다(Linux에서는 4096자).약 100자(107자리눅스).
- 첫 번째 질문:왜 그렇게 낮은 제한이 있습니까?
현재 작업 디렉터리를 변경하고 다양한 디렉터리에 모두 동일한 경로를 사용하는 여러 소켓 파일을 생성 하여 이 제한 사항을 해결하는 것이 가능한지 확인했습니다 ./myfile.sock
. 클라이언트 응용 프로그램이 예상된 서버 프로세스에 올바르게 연결되는 것 같습니다. lsof
그 중 동일한 소켓 파일 경로를 수신하고 있습니다.
- 이 해결 방법은 신뢰할 수 있습니까, 아니면 운이 좋았습니까?
- 이 동작은 Linux에만 해당됩니까, 아니면 이 해결 방법이 다른 Unix에도 적용될 수 있습니까?
답변1
snprintf()
및 를 사용하는 동안 오버런을 방지하기 위해 다른 플랫폼과의 호환성 또는 이전 항목과의 호환성 strncpy()
.
마이클 케리스크(Michael Kerrisk)가 설명합니다.그의 책~에서1165페이지- 57장, 소켓: Unix 도메인:
SUSv3은 sun_path 필드의 크기를 지정하지 않습니다. 초기 BSD 구현에서는 108바이트와 104바이트를 사용했으며 최신 구현(HP-UX 11)에서는 92바이트를 사용했습니다. 이식 가능한 응용 프로그램은 이 낮은 값으로 코딩해야 하며 snprintf() 또는 strncpy()를 사용하여 이 필드에 쓸 때 버퍼 오버런을 방지해야 합니다.
Docker 사람들은 심지어 일부 소켓의 길이가 110자이기 때문에 이를 비웃었습니다.
이것이 LINUX가 108자 소켓을 사용하는 이유입니다. 이것이 바뀔 수 있습니까? 물론. 그리고 이것이 우선 이전 운영 체제에서 이 제한이 만들어진 이유입니다.
답변을 인용하면 다음과 같습니다.
편리한 커널 데이터 구조에서 사용 가능한 공간을 일치시키기 위한 것이었습니다.
McKusick et.의 "4.4BSD 운영 체제의 설계 및 구현" 인용 알. (페이지 369):
메모리 관리 기능은 mbuf라는 데이터 구조를 중심으로 이루어집니다. Mbuf 또는 메모리 버퍼의 길이는 128바이트이며 이 공간 중 100 또는 108바이트는 데이터 저장용으로 예약되어 있습니다.
기타 OS(unix 도메인 소켓):
- 오픈BSD: 104자
- FreeBSD: 104자
- 맥 OS X 10.9: 104자
답변2
그 이유에 관해 nwildner는 이미 다음과 같은 글을 썼습니다.훌륭한 답변.
여기서는 상대 경로 사용법과 방법에 중점을 둘 것입니다.
내부적으로는 소켓 파일을 이름으로 조회할 수도 있지만(아마도) 일반적으로 inode로 조회합니다. Linux에서 이 조회는 unix_find_socket_byinode()
다음에 정의된 함수에 의해 보장됩니다.넷/유닉스/af_unix.c.
이는 다음과 같이 쉽게 확인할 수 있습니다.
- 두 개의 디렉터리를 생성합니다.ㅏ/그리고비/.
- 각 디렉터리 아래에서 동일한 이름을 가진 소켓 파일을 수신하는 프로세스를 만듭니다. 와 함께
socat
다음과 같은 명령을 사용합니다.
$ socat UNIX-LISTEN:./my.sock -
- 이제 이동하여 소켓 파일을 교환하십시오.A/my.sock에게비/그 반대.
- 이제부터 클라이언트 애플리케이션이 다음에 연결되면A/my.sock서버에 접속합니다비, 그리고 다음에 연결되면B/my.sock서버에 접속합니다ㅏ(통신이 끝나면 서버 프로세스는 자신의 소켓 파일이라고 생각되는 것을 합법적으로 삭제할 수 있습니다.)
나는 소수의 Unix 시스템(다양성을 얻기 위해 Linux Debian, FreeBSD 및 OpenIndiana)에서 이 동작을 확인했습니다. 따라서 이 동작은 표준은 아니더라도 적어도 널리 퍼져 있는 것 같습니다.
절대 경로는 일반적으로 클라이언트와 서버 프로세스 간의 규칙으로 사용됩니다. 그렇지 않으면 클라이언트 프로세스가 서버와의 초기 통신을 설정하는 방법을 알 수 없기 때문입니다.
그러나 이 초기 통신이 문제가 되지 않으면 소켓 파일 생성에 상대 경로를 사용하는 것이 안전해 보입니다. 그러면 소켓 파일 위치가 서버 프로세스에 의해 직접 제어되지 않을 때 경로 길이 문제를 피할 수 있습니다.