Provided for informative purposes only. The terms used for describing NAT behaviour in this article are based on classical STUN[RFC3489], which has been obsoleted by subsequent amendments. For the latest definition of NAT behaviour, please refer to [RFC4787]
full cone NAT = network traffic-initiated automatic port-forwarding managed by the kernel
xx-restricted cone NAT = traffic-initiated automatic port-forwarding with firewall implemented in someways
symmetric NAT != port-forwarding
The NAT device will also take the outer tuple(source host: port) into account upon receipt, alongside the NAT port itself.
Consequently, a symmetric NAT can map a single NAT port to multiple inner tuples(destination host: port) based on incoming packets' outer tuples(and the NAT port, of course).
cone NAT/port-forwarding = one-to-one mapping (NAT port, inner tuple)
symmetric NAT = one-to-one mapping (NAT port && outer tuple, inner tuple)
Is it possible to do a symmetric-to-symmetric UDP hole punching?
Symmetric-to-symmetric NAT traverse is still possible through guessing or using an oracle, but only if there is a predictable pattern, such as a linear increase, in the NAT ports being allocated on both sides.
There are some NAT behaviours hard to fit into any of those classical NAT categories proposed by RFC3489, why?
With tricks implemented, we can send packets from a different source outside the LAN to a symmetric NATed socket behind the NAT (i.e. Linux's Netfilter with several additional rules in place, such as DMZ or DNAT rules, which leads to a "full cone" test result using classical STUN[RFC3489]).
However, the port allocation behaviour is usually ambiguous in some NAT implementations; take Netfilter as an example. Technically, we can never say for sure using merely STUN if the port allocated on the NAT is, in fact, consistent or mutable for the same tuple inside the LAN. Consequently, any "cone NAT" device tested using STUN could turn out to be "a symmetric NAT in disguise" in the end. We would never know.