Fondamentalmente, non può essere fatto in modo efficiente.
La maggior parte delle reti P2P si basa su informazioni di seeding (elenchi di nodi esistenti a cui è possibile provare a connettersi). Prendo dalla tua domanda che vuoi una soluzione che non richiede l'informazione di seeding ai nodi.
Senza informazioni di seeding, i nodi nelle reti P2P sono limitati a provare indirizzi casuali. Questo può funzionare correttamente se (A) il numero di nodi P2P nella rete è grande e (B) molti / molti nodi hanno la capacità di accettare connessioni in ingresso (cioè, non sono dietro NAT).
Per 2 nodi su IPv4, questo significherà miliardi di pacchetti inviati prima che si scoprano a vicenda, se uno di loro può accettare connessioni in entrata.
Se nessuno dei due può accettare connessioni in entrata, deve tentare di connettersi l'un l'altro contemporaneamente per raggiungere l'attraversamento nat. La possibilità di successo è solo circa uno su 2 ^ 64 per tentativo. Questo perché ognuno deve indovinare l'indirizzo dell'altro correttamente. Questo semplicemente non funzionerà.
Ovviamente, tutto diventa più difficile con IPv6.