Это довольно сложно и интересно. Я уверен, что некоторые детали неверны, но обзор таков:
Программы уже могут общаться друг с другом через сервер Джоэла, поэтому они могут обмениваться информацией друг с другом и сервером Джоэла. Кроме того, у Джоэла есть свои внешние IP-адреса, и они предоставляют Джоэлу информацию о своих внутренних IP-адресах.
Они решили попробовать эту технику дырокола. Компьютер A устанавливает соединение TCP с компьютером B, используя внешний IP-адрес B. Он не пройдет, но он сообщит маршрутизатору A, что ему нужно разрешить входящие пакеты от B на данный порт.
Компьютер B делает то же самое, но его сообщение доходит до A, поскольку маршрутизатор A открыл комбинацию порта / ip, которая соответствует отправленной B (здесь происходит какое-то волшебство порта - это не тривиально, но выполнимо).
Маршрутизатор B помнит, что B инициировал соединение с A на заданном порту и IP-адресе, и поэтому пакеты A теперь также правильно проходят через B через свой маршрутизатор.
Так что на самом деле все довольно просто, но в реализации есть детали, особенно касающиеся того, как порты назначаются новым TCP-соединениям, и как маршрутизаторы NAT обычно обрабатывают запросы TCP и как они отображаются на внешние порты. Эти детали интересны и сложны.
-Adam