Open self-related opened 2 months ago
Как я понимаю, роутер выдаёт Not connected когда считает, что у него нету прямого подключения к Интернету. Понятно, что у роутера могут быть ложные определения доступности сети, но если предположить, что в среднем у пользователей доступность чаще определяется верно, то такой патч позволит им пробрасывать порт из недоступной сети в недоступную. Точно не помню, какие от этого негативные последствия, но это как минимум неверно логически.
Что интересно, в Transmission порт пробрасывается всегда и там тоже используется miniupnc с проверкой только на UPNP_IGD_VALID_CONNECTED - https://github.com/transmission/transmission/blob/1e16912ae4a20ca338cfe89c72418cd37eac0102/libtransmission/port-forwarding-upnp.cc#L270
Я не разобрался, как у них это реализовано. Возможно ли такое решение?
Я не разобрался, как у них это реализовано.
Наверно, с этого места стоит изучать: https://github.com/transmission/transmission/pull/6718
Пришлось собрать transmission-daemon и добавить в дебаг вывод после проверки UPNP_IGD_VALID_CONNECTED - там тоже всегда статус 2 и он не изменяется. Спустя несколько попыток реконнекта у меня он просто забивает на статус, хотя в коде не совсем понял, при каком условии, и кажется там Fail вообще не обрабатывается. https://github.com/transmission/transmission/pull/6718/commits/2698cac9b0a0e7422a5ce2a03887d7dfcd6645c7
if (
UPNP_GetValidIGD(devlist, &handle->urls, &handle->data, std::data(lanaddr), std::size(lanaddr) - 1, nullptr, 0)
== UPNP_IGD_VALID_CONNECTED)
{
...
}
else
{
handle->state = UpnpState::WillDiscover; //вот здесь новая попытка
...
}
enum class UpnpState : uint8_t
{
Idle,
WillDiscover, // next action is upnpDiscover()
inf port-forwarding.cc:216 State changed from 'Starting' to 'Not forwarded' (port-forwarding.cc:216)
inf port-forwarding.cc:216 State changed from 'Not forwarded' to 'Starting' (port-forwarding.cc:216)
Да, там все странно - отключил сейчас upnp на роутере и transmission бесконечно сыпет в лог уже больше получаса:
dbg port-forwarding-natpmp.cc:46 readnatpmpresponseorretry failed. Natpmp returned -7 (the gateway does not support nat-pmp); errno is 111 (Connection refused) (port-forwarding-natpmp.cc:46)
inf port-forwarding.cc:216 State changed from 'Starting' to 'Not forwarded' (port-forwarding.cc:216)
inf port-forwarding.cc:216 State changed from 'Not forwarded' to 'Starting' (port-forwarding.cc:216)
Возможно, проблема с пробросом в самом miniupnpc. Например qbittorrent судя по логам пробрасывает сразу же и без ошибок.
Возможно, проблема с пробросом в самом miniupnpc. Например qbittorrent судя по логам пробрасывает сразу же и без ошибок.
miniupnpc использует команду GetStatusInfo
для проверки статуса:
https://github.com/miniupnp/miniupnp/blob/d07b0a1a9d4ce62f36040d64a4b629a914950f9c/miniupnpc/src/miniupnpc.c#L494-L501
В libtorrent я вообще фразы GetStatusInfo
не нахожу. Видимо, ему всё равно.
Вот тут есть кое какое упоминание этой команды: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf
Интересно. Оказывается, в новой версии miniupnpc другие константы. Как пользователям библиотеки предполагается об этом узнавать?
Правда, дополнительный код - он всё равно "не единица".
Хм, на версии 2.2.8 клиент upnpc корректно пробрасывает сразу без флага -i. I2pd и transmission по прежнему отбрасывают state 2 .
ОДНАКО вот что я заметил в miniupnpc: https://github.com/miniupnp/miniupnp/commit/c0a50ce33e3b99ce8a96fd43049bb5b53ffac62f#diff-f4321c7c8d1e7ee67ca583dcc83ef3e391e233aa97c502fca50b32535d9cf936R624
Было:
/* in state 2 and 3 we don't test if device is connected ! */
if(state >= 2)
Стало:
/* in state 3 and 4 we don't test if device is connected ! */
if(state >= 3)
Видимо, в этом и суть новых констант, теперь state 2 считается приемлемым? Если так, то патч к i2pd это и делает, только тогда надо еще добавить в условие API 18, чтобы было корректно
I2pd и transmission по прежнему отбрасывают state 2 .
Отбрасывают не единицу.
Видимо, в этом и суть новых констант, теперь state 2 считается приемлемым?
Как я понял, состояние 2 теперь разбито на состояние 2 и 3. Но это по-прежнему не единица.
Может, ещё какое-то изменение есть.
Было: Стало:
Я это понимаю так: раз дошли до состояния 2 (или 3), то всё плохо и уже мелкие проблемы проверять смысла нету.
раз дошли до состояния 2 (или 3), то всё плохо
Но теперь это 3 и 4 в новой версии, а статус 2 проверяется вместе со статусом 1 по-умолчанию
Добавил вывод статуса в конец UPNP_GetValidIGD
printf("final state: %d\n", state);
Теперь вывод такой:
$ ./build/upnpc-static -r 12345 12345 udp
upnpc: miniupnpc library test client, version 2.2.8.
(c) 2005-2024 Thomas Bernard.
More information at https://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
List of UPNP devices found on the network :
desc: http://192.168.31.1:5351/rootDesc.xml
st: urn:schemas-upnp-org:device:InternetGatewayDevice:1
final state: 2
Found an IGD with a reserved IP address (*.*.*.*) : http://192.168.31.1:5351/ctl/IPConn
Local LAN ip address : 192.168.31.*
ExternalIPAddress = *.*.*.*
InternalIP:Port = 192.168.31.*:12345
external *.*.*.*:12345 UDP is redirected to internal 192.168.31.*:12345 (duration=0)
Т.е. статус 2 теперь не not connected, а reserved ip и проходит по умолчанию (место звездочек в первом случае тоже внешний айпи).
Но теперь это 3 и 4 в новой версии, а статус 2 проверяется вместе со статусом 1 по-умолчанию
Только это касается не библиотеки, а утилиты. Вот "правильная" строчка: https://github.com/miniupnp/miniupnp/blob/d07b0a1a9d4ce62f36040d64a4b629a914950f9c/miniupnpc/src/upnpc.c#L757
Кстати, они таки добавили константы.
Т.е. статус 2 теперь не not connected, а reserved ip и проходит по умолчанию
Так всё же - зачем i2pd нужен проброс с reserved ip? i2pd ведь белый ip нужен, доступный из Интернета.
Если же miniupnpc или железка отмечают белый IP как серый, то надо разбираться, почему.
i2pd ведь белый ip нужен
За nat ведь тоже можно получать прямые udp соединения. У меня на джава роутере upnp работал и показывал прямые SSU соединения в статистике. Соответственно, порт надо открыть, особенно, когда он меняется с каждым рестартом
"Пробитие" NAT к UPnP, насколько я знаю, не относится. Этим занимаются отдельные механизмы внутри i2pd (интродьюсеры).
Проблема: UPnP: Unable to find valid Internet Gateway Device: error 2
Подробнее: Предположительно, проблема в нестандартном IGD - https://github.com/dappnode/DNP_DAPPMANAGER/issues/312
Ручной форвард в miniupnpc выдает "Not connected IGD":
Однако с флагом -i (игнор) все корректно форвардится:
В i2pd/daemon/UPnP.h случай с not connected соответствует:
UPNP_IGD_VALID_NOT_CONNECTED = 2
Лог i2pd до фикса:
После:
Форвард проходит.