В чём принцип работы STUN?
STUN нужен, чтобы узнать свой внешний ip и, что важнее внешний порт ассоциированный с внутренним. Ещё STUN сервер нужен, чтобы выяснить тип NAT. Если у одного из Вас Symmetric, а у другого RestrictedCone или PortRestrictedCone, то можно забыть про P2P. Больше STUN не на что не годен. В случае VoIP, клиенты желающие соединиться  обмениваются через SIP адресами полученными через STUN и направляют на друг друга поток трафика. В случае restricted NAT передача должна начаться с обеих сторон иначе NAT принимающей стороны решит, что пакеты нужно отбросить. Teredo например начинает слать пакеты пустышки, получение которых символизирует, что соединение уже установлено. Вы можете написать собственный Teredo клиент по спецификации, она довольно простая.
STUN такой куций протокол потому, что он лишь дополнение для SIP. Но это не мешает использовать его для своих нужд.
tcp для p2p требует еще одного stun\turn\ice сервера для проведения хендшейка. иначе никак.

чтоб было чуть понятней в чем проблема - если второй клиент за натом, то внутри адрес у него какой-то 192.168.22.88, а наружу он идет через нат с ипшником 172.22.20.20. проблема в том, что за этим натом может быть еще несколько сотень других компов, каждый с которых (снаружи) виден под этим ипшником. Именно по этой причине попытке законнектится к ипшнику вашего друга заканчивается провалом. нат просто не понимает что с этим запросом делать, потому отбрасывает его.