Эта проблема входит в топ-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 «больше не работает …
Хорошо, после двух дней отладки (за день до того, как я написал вопрос, а затем сегодня) я нашел его.
Это был параметр backlog в вызове listen () для ОС, который был равен 0. Когда загружался UFW / iptables, это приводило к нефункциональному серверу и в противном случае к функциональному серверу.
Почему поведение отличается с загруженными iptables или нет, для меня загадка.
Эта почта Предположим, что резерв должен быть как минимум 16, даже если он установлен на 0. Возможно (и это я догадываюсь), когда iptables загружен, ядро больше не округляет аргумент backlog, и 0 заставляет его «не работать». Что я могу понять, так как очередь 0 не имеет смысла.
Тем не мение. Установка отставания до 64 решила мою проблему.
websocketPpServerObject.set_listen_backlog(64);
Также см эта тема GitHub если вы заинтересованы в более подробной информации.
Других решений пока нет …