суббота, 30 июня 2012 г.

Уязвимости серверов к медленному чтению

По мотивам старой статьи на habrahabr.

Когда я писал echo_server, этой статьи на Хабре еще не было. Но я думал о том, что клиент (remote peer) может «нарочно медленно» принимать данные. Именно поэтому я использую класс ma::cyclic_buffer, совмещающий в себе и буфер приема, и буфер отправки. Благодаря такому совмещению, мне, кажется, удалось более гибко распределить ресурсы сервера:
  • с одной стороны, я выставляю ограничение памяти (размер буфера) на всю сессию,
  • с другой – это ограничение динамически распределяется на буфер отправки и буфер приема одновременно, т.е. выделенное пространство используется максимально эффективно.
Кроме того, я реализовал таймаут. И не просто таймаут на отправку (хотя хватило бы и его), но совмещенный таймаут (+ сэкономил один таймер) «активности remote peer»:
в течение указанного для таймаута значения удаленный конец должен завершить хотя бы одну активную операцию ввода/вывода, если только таковая есть (еcли кому-то интересны подробности, спрашивайте в комментариях).
Конечно, это не полноценная защита. Но, IMHO, и сервер (middleware, application layer) надо проектировать так, чтобы минимизировать возможность проведения успешных атак (в т.ч. DOS) – в идеале вообще исключить их.

FAQ

Соберу-ка здесь некоторые полезные материалы по теме сокетов.

Начну с правильного завершения/закрытия TCP-сессии (сокета) с точки зрения Winsock (в Linux, полагаю, можно делать аналогично, т.е. данный подход одинаково хорошо сработает и в Windows и в Linux). Немногие статьи освещают эту тему. Почему-то закрытие TCP-сессии (равно как и останов сервера) часто обделяют должным вниманием.
Кому есть что добавить - милости прошу в комментарии.

Updated 2013/12/04:
RTFM: Йон Снейдер: "Эффективное программирование TCP/IP". Очень правильная книга, вправляющая мозги по поводу многих мифов вокруг TCP. Часто встречаю в сети (форумы, списки рассылок) вопросы, решаемые прямой отсылкой к соответствующей главе данной книги.

Updated 2019/03/13:
Asio, SSL, and scalability

Updated 2020/05/23:
Why does one NGINX worker take all the load?

воскресенье, 22 апреля 2012 г.

Немного новостей

Вышел очередной бета-релиз asio samples – 0.3.9.

Кроме исправления ошибок в этот релиз вошел сильно измененный Asio performance test client (проект asio_performance_test_client) из non-Boost версии Asio. Хотя данный тест, пожалуй, пригодится лишь для тестирования простейших серверов (TCP-echo/proxy), его отсутствие сильно «напрягало» – приходилось брать сторонние решения, которые работали не так, как ожидалось. Хотелось бы видеть этот тест и другие, связанные с ним, части asio samples в Boost версии Asio. Вот только с местом, куда скинуть предложение/исходники, я пока не определился – то ли на sf.net, то ли на github. Если последнее, то уместен был бы pull request, но, как я понимаю, для начала надо будет выкачать рабочую копию из своей branch, созданной на основе Asio master branch… лениво разбираться с git.

Кроме asio_performance_test_client я наконец-то довел до ума проекты для QMake – теперь есть возможность (скорее требование) указать локальную копию Boost, используемую для сборки. Для автоматической компоновки с Boost.Chrono (при наличии это библиотеки) пришлось почитать документацию к QMake :)

Не буду переписывать здесь release notes из списка рассылки asio-samples-users – добавлю лишь, что уже сегодня залил в trunk asio samples патч, заменяющий в Boost.Asio (Boost 1.49) все вызовы Win32 API InterlockedXXX на соответствующие макросы из boost/detail/interlocked.hpp. Почему автор Asio так и не перевел (см. мой вопрос в списке рассылки asio-users) Boost версию на эти макросы для меня остается загадкой (аргумент а-ля details/non-stable не принимается). Может ему просто лень настолько сильно разделять Boost и non-Boost версии?

среда, 30 ноября 2011 г.

Для "почитать"

Что-то зачастил я с подобными постами - но ведь интересно же, "как это делают люди".

Richard Jones: A Million-user Comet Application with Mochiweb, Part 3.
Even so, I think this could be generalized in such a way that would allow you to use Erlang for all the interesting stuff, and have a C+libevent process act as a dumb connection-pool. With a bit more wrapper code and callbacks into Erlang, you’d hardly need to know this was going on - the C program could be run as a driver or a C-node, and an Erlang wrapper could give you a decent api built on top of libevent.

Urban Airship Blog: C500k in Action at Urban Airship.
... we pressed on with a Java + Pure NIO implementation.

вторник, 11 октября 2011 г.

Чтиво

$3M инвестиций в NGINX.
Deep C (and C++) (сегодня запостили на RSDN) - каждый слайд, что называется, "в яблочко".
Overload 105 (см. Picking Patterns for Parallel Programs). Asio samples == almost C++ actors based on task based (fork/join) parallelism.

пятница, 30 сентября 2011 г.

Весёленький год

Мда. Этот год, наверное, поставил рекорд по остроте новостей с IT-фронта:
1. Nokia отвернулась от MeeGo и ищет спасения под крылом MS WP7
2. HP – рыба гниет с головы
3. Intel, что вы там курите? (комментарии особенно хороши)

Очень жаль, и Qt (в т.ч. соотв. подразделение Nokia) и MeeGo.