Ответ 1
У меня есть только один документ спецификации POSIX, который Системные интерфейсы, поэтому я сделаю все возможное отсюда.
Наша спецификация spelunking приключений должна, конечно, начинаться с 2.10.6 Использование опций, которая определяет опцию SO_REUSEADDR
следующим образом:
Параметр SO_REUSEADDR указывает, что правила, используемые при проверке адресов, указанных в bind(), должны разрешать повторное использование локальных адресов. Работа этого параметра зависит от протокола. Значение по умолчанию для SO_REUSEADDR выключено; то есть повторное использование локальных адресов не разрешено.
Этот параграф в принципе отказывается от какой-либо спецификации того, что этот вариант действительно делает, делегируя его спецификации спецификации базового протокола.
Раздел 2.10.17 Использование сокетов для локальных подключений UNIX описывает механизм создания сокетов домена UNIX, но на самом деле единственное, что он говорит нам, это то, что тип сокета постоянный использовать и какую структуру использовать для адресов. Документация для sockattr_un
struct сообщает нам только о ее формате, а не о его поведении на bind
.
Документация для bind
сама, по понятным причинам, является протокольно-агностикой, сообщая нам только, что происходит, когда адрес уже используется, а не обстоятельства, привязка одного и того же сокета.
Хотя он не является стандартным документом POSIX, Fujitsu имеет документ в API сокетов POSIX, который интересен, хотя бы потому, что он не относится конкретно к Linux или BSD. В разделе 2.6.4 этого документа говорится о поведении bind
в UNIX-сокетах:
Имя пути, которое должно быть указано в компоненте
sun.sun_path
, создается как файл в файловой системе, используяbind()
. Поэтому процесс, вызывающийbind()
, должен иметь права на запись в каталог, в котором должен быть записан файл. Система не удаляет файл. Поэтому он должен быть удален процессом, когда он больше не требуется.
Хотя это ничего не говорит о SO_REUSEADDR
в частности, он утверждает, что поведение bind
заключается в создании файла и что процесс связывания несет ответственность за его удаление, когда он больше не используется.
Наконец, это описание документа setsockopt
имеет следующие значения SO_REUSEADDR
:
Указывает, что правила проверки достоверности адресов, указанных для bind(), должны разрешать повторное использование локальных адресов при условии, что это поддерживается протоколом.
Таким образом, хотя это не делает особого упоминания о AF_UNIX
, оно подтверждает, что этот параметр не применяется ко всем протоколам.
Я также нашел (неавторизированное) резюме, описывающее намеченную цель SO_REUSEADDR
:
Эта опция сокета сообщает ядру, что даже если этот порт занят (в состоянии
TIME_WAIT
), продолжайте и повторно используйте его. Если он занят, но с другим состоянием, вы все равно получите сообщение об ошибке, которое уже используется.
Состояние TIME_WAIT
существует, главным образом, для сокетов, связанных с Интернетом, чтобы избежать привязки новой программы к порту, который недавно использовался другой программой, и непреднамеренно получать пакеты, относящиеся к старой программе. Эта проблема, возможно, неприменима к сокетам UNIX, потому что очень маловероятно, что две программы попытаются создать сокет по тому же пути, поэтому, если TIME_WAIT
не реализовано для сокетов UNIX, это может быть одно (приближение) объяснения почему SO_REUSEADDR
не относится к AF_UNIX
.