So perhaps we reached a point where it should be considered bad form for one to design protocols that are not NAT friendly then?
It's not hard to write a program that works well with NAT so long as the other end isn't also behind NAT. If /both/ ends are behind NAT it gets complicated. RFC 3459 classifies NAT's into 1 of 4 categories. Using the 4th category (Symmetric) it is impossible for two boxes both behind NAT to talk to each other without using an intermediate relay. You have to send "keep alives" to keep your "port forward" active, how often you send this extra (wasted) traffic is anyones guess. Many NAT boxes believe UDP is only used for DNS, and have timeouts appropriate for DNS queries or other protocols that don't have a large quiet times. Silence suppression on VoIP can be enough to break a NAT traversal. NAT traversal only really works for UDP. While in theory it is possible to do nat traversal with TCP, I've never head of it being practically used outside the lab. So if I have a "bulk transfer" program between two applications both behind NAT, the answer is it's effectively impossible (to my understanding). If what you're doing is "realtime" enough that you can use UDP with a straight face, then you can "mostly" get it right for NAT<->NAT boxes by using nat traversal techniques. Unless one end of them uses a Symmetric NAT. You can use UPnP and pray the users router is smart enough to deal with it. You could use "supernodes" (anyone running your program on a realworld IPv4) as proxies. But then who wants to be a supernode and have an increasing amount of traffic route through them? You could also use STUN as a proxy. How many STUN proxies are going to stick around if people keep using them as proxies tho? What happens if someone decides that since Nat traversal works with UDP so they start doing bulk transfers through UDP? Well, unless they fully implement congestion control without any glaring bugs, chances are the Internet would melt under congestion collapse. To me the only viable solution is to use IPv6 and require 6to4, Teredo or even a statically configured IPv6 over IP tunnel for NAT traversal. At least XP and Vista give this to me for free so I don't have to implement stuff to deal with all of this and the code I have to write and debug for this is minimal and easily tested.