Ядро Linux в комментариях

       

Struct msqid_ds


Объект msqid_ds представляет единственную очередь сообщений. Он имеет следующие члены:

  • msg_perm. Содержит информацию о том, каким процессам необходимо предоставить разрешение читать и писать в этой очереди сообщений.
  • msg_first и msg_last. Указывает на первое и последнее сообщения в очереди.
  • msg_stime и msg_rtime. Содержат данные, соответственно, о том, когда в последний раз в очередь было отправлено сообщение и когда в последний раз из очереди было считано сообщение. (Попробуйте решить задачу: когда член msg_stime последнего сообщения в очереди не равен члену msg_stime самой очереди? Существуют, по крайней мере, два ответа, но сейчас в вашем распоряжении есть только информация, которая позволяет найти лишь один правильный ответ— чтобы найти другие ответы, вам придется внимательно прочесть код.)
  • msg_ctime. Время последнего изменения состояния в очереди: время ее создания или время последней установки одного из ее параметров с использованием системного вызова msgctl.
  • wwait. Очередь процессов, ожидающих записи в очередь сообщений. Поскольку отправка сообщений является асинхронной, обычно процессы могут записать сообщение в очередь и продолжить свою работу. Но для обеспечения защиты от атак по принципу «отказа от обслуживания» очередь имеет максимальный размер — без этого предела процесс мог бы снова и снова посылать в очередь сообщения, которые никто не будет читать, заставляя ядро распределять память для каждого сообщения до тех пор, пока не будет исчерпана вся свободная память. Следовательно, после того, как очередь достигнет максимального размера, процесс, ожидающий отправки сообщения в очередь, должен будет ждать до тех пор, пока в очереди не освободится место для нового сообщения, или его попытка послать сообщение будет немедленно отвергнута (как будет показано ниже, процесс может сам выбрать правило поведения). Очередь wwait содержит идентификаторы процессов, которые решили ждать.
  • rwait. Аналогичным образом, обычно сообщения можно немедленно прочитать из очереди сообщений. А если в очереди нет сообщений? Опять-таки, процессы получают право сделать выбор: они могут либо снова вернуть себе контроль (получив код ошибки, сигнализирующий о неудаче в получении сообщения), либо перейти в состояние ожидания и ждать поступления сообщения.

  • msg_cbytes. Общее число байтов, содержащихся в настоящее время во всех сообщениях в очереди.


  • msg_qnum. Число сообщений в очереди. Не существует явного предела числа сообщений, которые могут быть поставлены в очередь, а это проблема, требующая решения, как описано далее в этой главе.


  • msg_qbytes. Максимальное число байтов, которое разрешено использовать для хранения всех сообщений в очереди; msg_cbytes сравнивается с msg_qbytes для определения того, есть ли еще место для нового сообщения. Значение msg_qbytes принято по умолчанию равным MSGMNB, однако этот предел может быть увеличен динамически пользователем с соответствующими правами.

    Величина MSGMNB установлена директивой #define равной 16384 байтам в строке . Существуют четыре причины применения такого низкого предела. Во-первых, на практике обычно редко возникает необходимость включать так много информации в конкретное сообщение, поэтому данный предел не является слишком ограничительным. Во-вторых, если отправители сообщений будут забегать слишком далеко вперед по сравнению с получателями сообщений, то, вероятно, нет никакого смысла позволять им и дальше работать в таком же темпе; они получают возможность на время остановиться, чтобы позволить получателям справиться с полученным заданием. В-третьих, этот предел в 16 Кб на очередь может в принципе быть умножен на 128 очередей, что составляет в сумме 2 Мб.

    Но основной причиной установки такого предела является предотвращение описанной выше атаки по принципу «отказа в обслуживании». Однако ничто не мешает приложениям посылать сообщения нулевой длины (т.е. пустые) сообщения. Эти сообщения не будут отражаться на величине msg_qbytes, а для заголовков сообщений все еще будет распределяться память, поэтому возможность атаки по принципу «отказа в обслуживании» все еще сохраняется. Один из способов решения этой проблемы состоит в наложении независимого предела на число сообщений, которым разрешено находиться в очереди; вторым решением является вычитание из msg_qbytes размера всего сообщения, включая заголовки. Третье решение, безусловно, состоит в запрещении пустых сообщений, но это привело бы к нарушению совместимости.

  • msg_lspid и msg_lrpid. Идентификаторы процессов последнего отправителя сообщения и последнего получателя сообщения.



  • Содержание раздела