Проблема с принятием соединения с использованием websocketpp с включенным брандмауэром

Эта проблема входит в топ-5 самых странных вещей, с которыми я когда-либо сталкивался. Поэтому, пожалуйста, потерпите меня.

Я использую Arch Linux (до 2017-03-09) с брандмауэром UFW.

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

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

И UFW также разрешает весь трафик на локальном хосте, но это не имеет значения, если я подключаюсь локально или нет.

Я проверил проблему с примером эхо-сервера в хранилище websocketpp тоже.

Убедитесь, что мое приложение прослушивает порт 9002

sudo netstat -lnp | grep 900
tcp6       0      0 :::9002                 :::*                    LISTEN      12695/./bin/echo_se

Здесь мы видим, что эхо-сервер привязан к ipv6. Но переход на ipv4 только не помогает. Уже попробовал.

Вывод с эхо-сервера с отладкой

[2017-03-09 11:38:06] [devel] endpoint constructor
[2017-03-09 11:38:06] [devel] server constructor
[2017-03-09 11:38:06] [devel] asio::init_asio
[2017-03-09 11:38:06] [devel] set_message_handler
[2017-03-09 11:38:06] [devel] asio::listen
[2017-03-09 11:38:06] [devel] create_connection
[2017-03-09 11:38:06] [devel] asio con transport constructor
[2017-03-09 11:38:06] [devel] connection constructor
[2017-03-09 11:38:06] [devel] transport::asio::init
[2017-03-09 11:38:06] [devel] asio::async_accept

Я использую telnet, чтобы попытаться подключиться (так как на данный момент я забочусь только о рукопожатии tcp

telnet localhost 9002
Trying ::1...
(eventually timeout)

И если я закрою эхо-сервер, так что приложение больше не будет слушать. Тогда я получаю (как и ожидалось)

telnet localhost 9002
Trying ::1...
Connection failed: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

Итак, теперь ОС замечает, что никто не слушает и отправляет соединение, отказано.

И правила UWF:

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
22                         ALLOW       Anywhere
7000:8000/udp              ALLOW       Anywhere
7000:8000/tcp              ALLOW       Anywhere
9000:9500/tcp              ALLOW       Anywhere
9002                       ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
22 (v6)                    ALLOW       Anywhere (v6)
7000:8000/tcp (v6)         ALLOW       Anywhere (v6)
9000:9500/tcp (v6)         ALLOW       Anywhere (v6)
9002 (v6)                  ALLOW       Anywhere (v6)

Я должен также упомянуть, что другие серверы. Например, сервер asio telnet с минимальным бустом, сервер на базе zmq и т. Д., Который я пробовал на том же порту, работает просто отлично.

Итак, я думаю, что это должно быть что-то с websocketpp, но я не понимаю, что это может быть. Это кажется невозможным, поскольку рукопожатие tcp выполняется ниже уровня приложения.

Любые идеи ценятся на этом этапе.

Для полноты. После отключения UFW и перезагрузки я получаю от эхо-сервера:

2017-03-09 11:49:17] [devel] endpoint constructor
[2017-03-09 11:49:17] [devel] server constructor
[2017-03-09 11:49:17] [devel] asio::init_asio
[2017-03-09 11:49:17] [devel] set_message_handler
[2017-03-09 11:49:17] [devel] asio::listen
[2017-03-09 11:49:17] [devel] create_connection
[2017-03-09 11:49:17] [devel] asio con transport constructor
[2017-03-09 11:49:17] [devel] connection constructor
[2017-03-09 11:49:17] [devel] transport::asio::init
[2017-03-09 11:49:17] [devel] asio::async_accept
[2017-03-09 11:49:23] [devel] asio::handle_accept
[2017-03-09 11:49:23] [devel] connection start
[2017-03-09 11:49:23] [devel] asio connection init
[2017-03-09 11:49:23] [devel] asio connection handle pre_init
[2017-03-09 11:49:23] [devel] asio connection post_init
[2017-03-09 11:49:23] [devel] asio connection handle_post_init
[2017-03-09 11:49:23] [devel] connection handle_transport_init
[2017-03-09 11:49:23] [devel] connection read_handshake
[2017-03-09 11:49:23] [devel] asio async_read_at_least: 1
[2017-03-09 11:49:23] [devel] create_connection
[2017-03-09 11:49:23] [devel] asio con transport constructor
[2017-03-09 11:49:23] [devel] connection constructor
[2017-03-09 11:49:23] [devel] transport::asio::init
[2017-03-09 11:49:23] [devel] asio::async_accept
[2017-03-09 11:49:23] [devel] asio post init timer cancelled

И это в телнет:

telnet localhost 9002
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

Так что тогда все работает безупречно.

И «после sudo ufw включи && sudo ufw disable «больше не работает …

1

Решение

Хорошо, после двух дней отладки (за день до того, как я написал вопрос, а затем сегодня) я нашел его.

Это был параметр backlog в вызове listen () для ОС, который был равен 0. Когда загружался UFW / iptables, это приводило к нефункциональному серверу и в противном случае к функциональному серверу.

Почему поведение отличается с загруженными iptables или нет, для меня загадка.

Эта почта Предположим, что резерв должен быть как минимум 16, даже если он установлен на 0. Возможно (и это я догадываюсь), когда iptables загружен, ядро ​​больше не округляет аргумент backlog, и 0 заставляет его «не работать». Что я могу понять, так как очередь 0 не имеет смысла.

Тем не мение. Установка отставания до 64 решила мою проблему.

websocketPpServerObject.set_listen_backlog(64);

Также см эта тема GitHub если вы заинтересованы в более подробной информации.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]