Its been years since I last worked with STUN. First get your code working between 2 PCs NOT separated by NAT. Then get your code working between 2 PCs with local software firewalls (think ZoneAlarm). Then get your code working between real Linksys box NAT. Per Wikipedia,
http://en.wikipedia.org/wiki/Full_cone_NAT#Full-cone_NAT and
http://en.wikipedia.org/wiki/STUN, STUN usually doesn't work against ISP/Linksys box NAT (1 public IP for many private IPs), only "firewalls". Some corporate and university networks that were well endowed in 90s and 80s with whole Class As and Class Bs give FIREWALLED public IPs to all the internal wifi and desktop workstations, STUN was designed for and basically only works for this case.
I think I remember some algorithms for symmetric/linksys NAT where the NATed client starts sending packets out to a selected server, the server sees all the packets and their source ports (source port selected by NAT box), and the server sends the port increments to the NATed client, I think the hack is that most OSes/NAT boxes allocate source ports on upticking counters (or less often, lowest port first, subject to a multi minute no reuse timer), a pattern can be identified, once both NATed clients see the port allocation patterns, they tell each other their external public IP side source port allocation patterns and they try to DOS/brute force the NAT tables of their NAT boxes until a race condition causes both NAT boxes to simultaneously add matching routes (from private IP side to public internet side packets of course) and a link is broken through. There are only 2^16 (65K) ports, so its not impossible. Most NAT boxes aren't smart to ban their private IP clients from connection flooding the NAT box route table. See
http://en.wikipedia.org/wiki/UDP_hole_punching and
http://en.wikipedia.org/wiki/TCP_hole_punching.