Короче разобрался я со своим роутером)) Всё работает. Тут подсказали -
https://gamedev.ru/code/forum/?id=50491&page=2
Для проверки я взял простой роутер и посмотрел как там работает UDP (проброска портов отключена). Измерил все тайминги))
Схема такая: сервер (10.0.0.1) --- (WAN | роутер | LAN) --- сервер (192.168.0.1)
1. Из внешней сети (10.0.0.1) во внутреннюю (192.168.0.1) попасть невозможно так как порты на роутере закрыты.
2. Из внутренней сети (192.168.0.1) во внешнюю сеть (10.0.0.1) попасть можно.))
3. Допустим сервер (192.168.0.1) отправляет UDP пакет серверу (10.0.0.1).
4. Роутер делает запись в таблице NAT (связка "порт == IP" ).
5. После отправки UDP пакета роутер включает таймер примерно на 20 секунд.
6. Если по истечении 20 секунд ответ так и не пришёл, роутер удаляет из таблицы NAT запись о сокете. После этого из внешней сети (10.0.0.1) во внутреннюю (192.168.0.1) попасть невозможно.
7. Допустим ответ пришёл. Тогда роутер устанавливает таймер примерно на 30 секунд.
8. Далее идёт обмен данными между серверами... сервер (192.168.0.1) << >> сервер (10.0.0.1)...
9. При каждом новом пакете роутер автоматически устанавливает таймер примерно на 2...3 минуты.
10. Если пакетов больше нет, то через 2...3 минуты срабатывает тайм-аут и роутер удаляет из таблицы NAT запись о сокете. После этого из внешней сети (10.0.0.1) во внутреннюю (192.168.0.1) попасть невозможно.
11. При передачи пакетов порты (Source port и Destination port) роутер не меняет. Роутер меняет только IP (Source IP и Destination IP).
12. Вывод: Для поддержания связи по UDP надо непрерывно что-то передавать... например пустые пакеты... не реже чем каждые 2...3 минуты )) Чтоб не срабатывал тайм-аут и роутер удаляет из таблицы NAT запись о сокете.
По сути это получается тот же самый keep-alive как в TCP... или как в браузере... или как в HTTP(S)/WebSockets....
Пипец))
Ну зато теперь я точно знаю как работает мой роутер))