udp-клієнт, що надсилає ICMP «порт недоступний» під час отримання повідомлень із сервера


3

(Примітка. Я перемістив це запитання із StackOverflow, оскільки його слід вважати поза темою, тут краще підходить і досі не вирішено)

У мене є udp-клієнт, який використовує luasocket, в основному це робить (з кількома шарами абстракції, але ось що там відбувається):

s=socket.udp()
s:setsockname("*",0)
s:setpeername(socket.dns.toip("example.com"),64299)
s:settimeout(0)
s:send(...)
s:settimeout(10)
msg,err=s:receive()
s:settimeout(0)
print(msg,err)

побачивши все добре у виведенні налагодження сервера (ssh на віддалений хост), я отримую помилку "timeout" у клієнті.

під час огляду всього за допомогою проводки на стороні клієнта, я бачу пакет, який мій клієнт надіслав, і пакет відповідей від сервера (правильний порт і все), і пакет ICMP "порт недоступний", надісланий від мого клієнтського хоста на сервер у відповідь на це (правильна) відповідь.

що там відбувається? Я спробував усе, включаючи скидання iptables, щоб "прийняти все", але мій клієнт все одно надсилає "порт недоступним".

відповідні пакети:

From            To                  Len Description
192.168.2.100   95.143.172.171  UDP 61  Source port: 45025  Destination port: 64299
  000e8f11e7000025229835a908004500002f4008400040112b6fc0a802645f8facabafe1fb2b001b28d794d2000ec8360100aa81a477616e74a3756964
95.143.172.171  192.168.2.100   UDP 60  Source port: 64299  Destination port: 45025
  0025229835a9000e8f11e70008004500002b000040003911727b5f8facabc0a80264fb2bafe100172e8d94d2000e0ea10100a681a3756964ff000000
192.168.2.100   95.143.172.171  ICMP 85 Destination unreachable (Port unreachable)
  000e8f11e7000025229835a9080045c00047061d00004001a492c0a802645f8facab0303cc6c000000004500002b000040003911727b5f8facabc0a80264fb2bafe100172e8d94d2000e0ea10100a681a3756964ff

Брандмауер, якщо це важливо (що я не думаю, оскільки iptables не збільшує жодних лічильників пакетів INPUT, поки це відбувається):

$ sudo iptables -S
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --sport 64299 -j ACCEPT
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i eth0 -p tcp -m tcp --dport 10001:30000 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o lo -j ACCEPT

і клієнт, і сервер використовують абсолютно один і той же код, тому щось на хості мого клієнта, здається, перешкоджає вхідному пакету відповідей.

Хронологія TL; DR:

  • клієнтська програма відкриває UDP-сокет, "підключаючись" до сервера
  • клієнтська програма надсилає пакет запитів
  • серверна програма отримує пакет запитів
  • серверна програма надсилає пакет відповідей
  • клієнт-хост отримує пакет відповідей (підтверджений проводкою на клієнті)
  • клієнт-хост надсилає порт ICMP недоступним (помічено в проводці клієнта)
  • клієнтська програма отримує час очікування читання через 10 секунд
  • (тільки що спробував :) надсилання більше пакетів від клієнта на сервер справді працює, тому сокет не закрився.

Чи знайшли ви це рішення? Зараз я стикаюся з тим же питанням
vk_gst

@vk_gst я це зробив, але, на жаль, я вже не знаю напевно, як, і я вже не маю цього старого коду, але я думаю, що це було щось пов'язане з тим, як luasocket обробляє UDP і setpeername, я думаю, що було щось недокументована потворність там відбувається, перше, що я б спробував, - це надсилати його чітко до віддаленого ip: порту кожного разу (я думаю, що є функція "надіслати"), а не намагатися, щоб сокет пам'ятав однолітка. Я думаю, що проблема полягала в тому, що, коли ви встановлюєте ім'я користувача, воно переходить у якийсь "надіслати тільки в той режим", і забуде прийняти вхідні пакети чи щось подібне.
нечіп

@vk_gst, але, як я вже сказав, не на 100% впевнений, це також могло бути деякою дивністю з мережевим обладнанням, що грає в це, але я не думаю, що так.
нечіп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.