Perché la lunghezza del percorso del socket è limitata a cento caratteri?


18

Sui sistemi Unix i nomi dei percorsi di solito non hanno praticamente limiti di lunghezza (beh, 4096 caratteri su Linux) ... ad eccezione dei percorsi dei file socket che sono limitati a circa 100 caratteri (107 caratteri su Linux ).

  • Prima domanda: perché un limite così basso?

Ho verificato che sembra possibile aggirare questa limitazione modificando l'attuale directory di lavoro e creando in varie directory diversi file socket tutti usando lo stesso percorso ./myfile.sock: le applicazioni client sembrano connettersi correttamente ai processi server previsti anche se lsofmostra tutto di loro in ascolto sullo stesso percorso del file socket.

  • Questa soluzione alternativa è affidabile o sono stato solo fortunato?
  • Questo comportamento è specifico di Linux o questa soluzione alternativa può essere applicabile anche ad altri Unix?

Il limite è ancora più basso (104) sugli attuali sistemi OpenBSD o Mac OS X 10.11.
thrig

La cosa importante è che deve essere inferiore a 108, per motivi di compatibilità :)

AFAIK ha 108 caratteri su Linux. Controlla / usr/include/$arch-linux-gnu/sys/un.h sul tuo computer.
schaiba,

@schaiba: 108 byte, il che significa una stringa di 107 caratteri terminata da un terminatore null.
WhiteWinterWolf

Risposte:


18

Compatibilità con altre piattaforme o compatibilità con elementi meno recenti per evitare sovraccarichi durante l'utilizzo di snprintf()e strncpy().

Michael Kerrisk spiega nel suo libro alla pagina 1165 - Capitolo 57, Socket: dominio Unix:

SUSv3 non specifica la dimensione del campo sun_path. Le prime implementazioni di BSD utilizzavano 108 e 104 byte e un'implementazione contemporanea (HP-UX 11) utilizza 92 byte. Le applicazioni portatili dovrebbero codificare su questo valore inferiore e utilizzare snprintf () o strncpy () per evitare sovraccarichi del buffer durante la scrittura in questo campo.

I ragazzi di Docker lo hanno persino preso in giro, perché alcune prese erano lunghe 110 caratteri:

Questo è il motivo per cui LINUX utilizza una presa di 108 caratteri. Questo potrebbe essere cambiato? Ovviamente. E questo è il motivo per cui in primo luogo questa limitazione è stata creata su sistemi operativi meno recenti:

Citando la risposta:

Doveva corrispondere allo spazio disponibile in una pratica struttura di dati del kernel.

Citando "La progettazione e l'implementazione del sistema operativo 4.4BSD" di McKusick et. al. (pagina 369):

Le strutture di gestione della memoria ruotano attorno a una struttura di dati chiamata mbuf. I Mbuf, o buffer di memoria, sono lunghi 128 byte, con 100 o 108 byte di questo spazio riservato per l'archiviazione dei dati.

Altri sistemi operativi (socket di dominio unix):


1
SUSv3 XNET era silenzioso perché non vi era consenso sulla questione.
fpmurphy

Hai qualche link per provare il tuo punto di vista?

Grazie per questa risposta È affidabile utilizzare diversi file socket con nomi identici rispetto a diverse directory di lavoro (ad esempio, creare un file socket denominato ./my.socketsotto la directory A/e un altro file socket denominato anche ./my.socketsotto la directory B/)? lsofnon fa alcuna distinzione tra i due file socket, tuttavia sembra ancora funzionare, ma mi chiedo se questo è solo perché sono fortunato. Questa sarebbe una buona soluzione per creare file socket sotto un percorso che è già più lungo della dimensione consentita.
WhiteWinterWolf

La ricerca di socket unix sul mio mailserver, sembra portare il nome completo del percorso: lsof -U| grep amavis(newline)amavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock

Sì, lo so che è insolito, quindi la mia domanda qui;)! Per quello che ho testato, i nomi relativi funzionano, ma mi sembra ancora strano ... ma funziona. La mia applicazione non è a livello di sistema, quindi i file socket vengono archiviati con tutti gli altri dati dell'applicazione in una posizione controllata dall'utente, che è fortemente preferita ma con un percorso potenzialmente troppo lungo, oppure posso ingombrare /tmpcon tonnellate di directory non cancellate con nomi univoci ciascuna contenente un singolo file socket (assolutamente brutto, ma portatile e sicuro).
WhiteWinterWolf

5

Per quanto riguarda il perché, nwildner ha già scritto una risposta eccellente .

Qui mi concentrerò solo su come e il relativo utilizzo del percorso.

Internamente, mentre il file socket può anche essere cercato per nome (suppongo), di solito sono cercati per inode. In Linux, questa ricerca è assicurata dalla funzione unix_find_socket_byinode()definita in net / unix / af_unix.c .

Questo può essere facilmente verificato come segue:

  • Creare due directory A / e B / .
  • Sotto ogni directory, fare in modo che un processo ascolti i file socket con lo stesso nome. Con socatte useresti un comando come:
$ socat UNIX-LISTEN:./my.sock -
  • Ora scambia i file socket spostando A / my.sock su B / e viceversa.
  • D'ora in poi, se l'applicazione client si connette a A / my.sock contatterà il server B e se si connette a B / my.sock contatterà il server A (tenere presente che al termine della comunicazione il processo del server potrebbe cancellare legittimamente quello che ritiene essere il proprio file socket).

Ho verificato questo comportamento su una manciata di sistemi Unix (Linux Debian, FreeBSD e OpenIndiana per ottenere un po 'di diversità), quindi questo comportamento sembra essere almeno diffuso, se non standard.

I percorsi assoluti vengono generalmente utilizzati come convenzione tra i processi client e server, poiché il processo client potrebbe non sapere altrimenti come stabilire la comunicazione iniziale con il server.

Tuttavia, se questa comunicazione iniziale non è un problema, sembra quindi sicuro utilizzare percorsi relativi per la creazione di file socket, consentendo di evitare problemi di lunghezza del percorso quando il percorso del file socket non è controllato direttamente dal processo del server.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.