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

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

Я использую Arch Linux (обновленный по состоянию на 09.03.2017) с брандмауэром ufw.

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

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

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

Я проверил проблему на примере эхо-сервера в репозитории 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)             

Я также должен упомянуть, что другие серверы. Например, сервер telnet asio с минимальным повышением, сервер на основе 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 enable && sudo ufw disable" больше не работает ...


person tkarls    schedule 09.03.2017    source источник


Ответы (1)


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

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

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

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

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

websocketPpServerObject.set_listen_backlog(64);

Также см. эту ветку github, если вас интересуют более подробные сведения.

person tkarls    schedule 09.03.2017