¿Por qué la longitud de la ruta del socket está limitada a cien caracteres?

¿Por qué la longitud de la ruta del socket está limitada a cien caracteres?

En los sistemas Unix, los nombres de ruta prácticamente no tienen limitación de longitud (bueno, 4096 caracteres en Linux)... excepto las rutas de archivos de socket que están limitadas aalrededor de 100 caracteres(107 caracteres enlinux).

  • Primera pregunta:¿Por qué una limitación tan baja?

He comprobado que parece posible solucionar esta limitación cambiando el directorio de trabajo actual y creando en varios directorios varios archivos de socket, todos usando la misma ruta ./myfile.sock: las aplicaciones cliente parecen conectarse correctamente a los procesos del servidor esperados, aunque lsofmuestra todos de ellos escuchando en la misma ruta del archivo de socket.

  • ¿Es confiable esta solución o simplemente tuve suerte?
  • ¿Este comportamiento es específico de Linux o esta solución alternativa también puede aplicarse a otros Unix?

Respuesta1

Compatibilidad con otras plataformas o compatibilidad con cosas más antiguas para evitar sobrecargas al usar snprintf()y strncpy().

Michael Kerrisk explica ensu libroen elpágina 1165- Capítulo 57, Sockets: dominio Unix:

SUSv3 no especifica el tamaño del campo sun_path. Las primeras implementaciones de BSD utilizaban 108 y 104 bytes, y una implementación contemporánea (HP-UX 11) utiliza 92 bytes. Las aplicaciones portátiles deben codificar con este valor más bajo y usar snprintf() o strncpy() para evitar desbordamientos del búfer al escribir en este campo.

Los chicos de Docker incluso se burlaron de ello, porque algunos sockets tenían 110 caracteres:

Es por eso que LINUX utiliza un socket de 108 caracteres. ¿Se podría cambiar esto? Por supuesto. Y esta es la razón por la que en primer lugar se creó esta limitación en Sistemas Operativos más antiguos:

Citando la respuesta:

Era para igualar el espacio disponible en una práctica estructura de datos del kernel.

Citando "El diseño y la implementación del sistema operativo 4.4BSD" de McKusick et. Alabama. (página 369):

Las funciones de gestión de la memoria giran en torno a una estructura de datos llamada mbuf. Los Mbufs, o buffers de memoria, tienen una longitud de 128 bytes, con 100 o 108 bytes de este espacio reservados para el almacenamiento de datos.

Otros sistemas operativos (sockets de dominio Unix):

Respuesta2

En cuanto al por qué, nwildner ya escribió unexcelente respuesta.

Aquí solo me centraré en el cómo y el uso relativo de la ruta.

Internamente, aunque el archivo socket también se puede buscar por nombre (supongo), normalmente se busca por inodo. En Linux, esta búsqueda está garantizada por la función unix_find_socket_byinode()definida ennet/unix/af_unix.c.

Esto se puede comprobar fácilmente de la siguiente manera:

  • Crear dos directoriosA/yB/.
  • Debajo de cada directorio, haga que un proceso escuche los archivos de socket que llevan el mismo nombre. Consocatusarías un comando como:
$ socat UNIX-LISTEN:./my.sock -
  • Ahora intercambie los archivos de socket moviendoA/mi.calcetínaB/y viceversa.
  • De ahora en adelante, si la aplicación cliente se conecta aA/mi.calcetínse pondrá en contacto con el servidorB, y si se conecta aB/mi.calcetínse pondrá en contacto con el servidorA(Sin embargo, tenga en cuenta que cuando finaliza la comunicación, el proceso del servidor puede eliminar legítimamente lo que cree que es su propio archivo de socket).

Verifiqué este comportamiento en un puñado de sistemas Unix (Linux Debian, FreeBSD y OpenIndiana para obtener cierta diversidad), por lo que este comportamiento parece estar al menos muy extendido, si no es estándar.

Las rutas absolutas se utilizan generalmente como una convención entre los procesos del cliente y del servidor, ya que de otro modo el proceso del cliente puede no saber cómo establecer la comunicación inicial con el servidor.

Sin embargo, si esta comunicación inicial no es un problema, parece seguro usar rutas relativas para la creación de archivos de socket, lo que permite evitar problemas con la longitud de la ruta cuando la ubicación del archivo de socket no está controlada directamente por el proceso del servidor.

información relacionada