Запуск сетевых служб через xinetd

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

Конфигурация xinetd, как правило, разделяется на две части: значения по умолчанию – /etc/xinetd.conf и настройки для отдельных служб, по одному файлу в каталоге /etc/xinetd.d/ на службу.

Чтобы запустить свою сетевую службу, необходимо создать ещё один файл в /etc/xinetd.d/. Имя файла особого значения не имеет, но обычно выбирается по имени службы. Предположим, что служба называется mynetd, запускается от имени пользователя user1 и выполняет команду sleep 10. Служба должна ожидать TCP соединение на порту 8888.

Конфигурационный файл /etc/xinetd.d/mynetd будет выглядеть так:

service mynetd
{
    disable = no
    # Если не написать UNLISTED, то xinetd будет искать имя службы и номер порта
    # в файле /etc/services
     type = UNLISTED

    # stream = TCP, datagram = UDP
    socket_type = stream
    port = 8888
    # Можно считать, что для протокола TCP wait всегда равен 'no',
    # а для протокола UDP – всегда 'yes'
    wait = no

    user = user1
    # При считывании конфигурации файл службы должен существовать и заданный пользователь
    # должен иметь право на его выполнение
      server = /bin/sleep
      server_args = 10
}

Параметр wait интерпретируется следующим образом: если socket_type = datagram и wait = yes, то при появлении на порту данных стартует новый процесс со входом/выходом, перенаправленным в сокет. Пока этот процесс не завершится, xinetd не контролирует наличие новых данных на порту, оставляя их запущенной программе. Если поставить wait = no, то на каждую дейтаграмму будет запускаться новый процесс, разделяющий со своими предшественниками общий сокет. В такой ситуации невозможно предсказать, какой копии программы достанутся входные данные из сокета. В принципе, такой подход возможен, если обработка дейтаграммы идёт долго, а писать многопоточный сервис лень. Для TCP ситуация обратная, wait = yes имеет смысл только для многопоточных программ, иначе первый процесс захватит сокет и не отдаст его, пока программа не завершится.