Почему длина пути сокета ограничена сотней символов?

Добавьте в начало сценария следующее:

trap 'echo "Error $? at $LINENO; aborting." 1>&2; exit $?' ERR

Затем, в любое время, когда что-либо вызывает неперехваченную ошибку, сценарий сработает с указанным выше сообщением и завершит работу. с кодом выхода ошибки. Вы можете изменить $? на 1 , если вы действительно хотите использовать код выхода 1 для любой ошибки.

19
25.05.2017, 02:07
2 ответа

Совместимость с другими платформами или совместимость со старыми версиями, чтобы избежать переполнения при использовании snprintf() и strncpy().

Майкл Керриск объясняет в своей книге на странице 1165 - Глава 57, Сокеты: домен Unix:

SUSv3 не определяет размер поля sun_path. Ранние реализации BSD использовали 108 и 104 байта, а одна современная реализация (HP-UX 11) использует 92 байта. Портативные приложения должны кодировать это более низкое значение и использовать snprintf() или strncpy(), чтобы избежать переполнения буфера при записи в это поле.

Ребята из Docker даже посмеялись над этим, потому что некоторые сокеты имели длину 110 символов:

Вот почему в LINUX используется 108-символьный сокет. Можно ли это изменить? Конечно. И это причина, по которой в первую очередь это ограничение было создано для старых операционных систем:

Цитирование ответа:

Это должно было соответствовать пространству, доступному в удобной структуре данных ядра.

Цитирование «Проектирование и реализация операционной системы 4.4BSD» МакКьюсик и др. др.(стр. 369):

Средства управления памятью вращаются вокруг структуры данных. называется мбуф. Mbuf, или буферы памяти, имеют длину 128 байт, со 100 или 108 байт этого пространства зарезервировано для хранения данных.

Другие ОС (сокеты домена unix):

27
27.01.2020, 19:45

По поводу того, почему, nwildner уже написал отличный ответ .

Здесь я просто сосредоточусь на том, как и на использовании относительного пути.

Внутренне, в то время как файл сокета также можно искать по имени (Я думаю ), они обычно ищутся по индексному узлу. В Linux этот поиск обеспечивается функцией unix_find_socket_byinode(), определенной в net/unix/af _unix.c .

Это можно легко проверить следующим образом:

  • Создайте два каталога A/ и B/ .
  • В каждом каталоге заставьте процесс прослушивать файлы сокетов с тем же именем.Сsocatвы должны использовать такую ​​команду, как:
$ socat UNIX-LISTEN:./my.sock -
  • Теперь обменяйтесь файлами сокетов, переместив A/my.sock в B/ и наоборот -.
  • Отныне, если клиентское приложение подключается к A/my.sock , оно будет связываться с сервером B , а если оно подключается к B/my.sock он свяжется с сервером A(обратите внимание, что когда связь завершается, серверный процесс может законно удалить то, что он считает своим собственным файлом сокета ).

Я проверил это поведение на нескольких Unix-системах (Linux Debian, FreeBSD и OpenIndiana, чтобы получить некоторое разнообразие ), поэтому такое поведение кажется по крайней мере широко -распространенным, если не стандартным.

Абсолютные пути обычно используются в качестве соглашения между клиентским и серверным процессами, поскольку в противном случае клиентский процесс может не знать, как установить начальную связь с сервером.

Однако, если этот первоначальный обмен данными не является проблемой, представляется безопасным использовать относительные пути для создания файлов сокетов, что позволяет избежать проблем с длиной пути, когда расположение файла сокета не контролируется серверным процессом напрямую.

8
27.01.2020, 19:45

Теги

Похожие вопросы