RFC6886 and RFC6887) which provide ways to get through NAT and firewalls.
What's the problem?
The original design of the Internet had all device's interfaces having a globally unique IP address that could send and receive packets on the Internet as a whole. This is great but for two small flaws: (a) There were not enough IPv4 addresses for that, and (b) Code is stupid, and hackers are not, and so we need firewalls.
So the classic scenario is a network (home or office) behind a router which does NAT and has one external IPv4 address (which may or may not occasionally change).
Please! NAT is not a firewall!
And yes, even FireBricks allow this set up, doing basic NAT on all outgoing sessions as well as allowing a wide variety of mapping configurations - if you can be bothered to set them up.
The classic scenario has a pretty simple router and simpler end users where they do not want the hassle of configuring mappings, and so this causes issues with anything on your network which would like an "incoming connection" to get to it.
NAT is evil!
NAT is a problem for so many reasons. It stifles development of protocols. It just makes life difficult. The usually answer is, of course, use IPv6.
The problem is that people still need the fire-walls. So even on IPv6 you have to ask how the incoming connections get past the fire-wall?
Have a protocol so devices on your LAN can tell your router to map or allow some incoming connections. Simples!
This started with uPnP (Universal Plug 'n' Play). Yes, 'n' should be 'and' and so it should be uPaP, but what the hell? My understanding of uPnP is it is a can of worms, so we have steered clear of that, sorry.
However, there is more. There are newer protocols. NAT-PMP (Network Address Translation - Port Mapping Protocol), and PCP (Port Control Protocol, not angel dust, honest).
The NAT-PMP (RFC6886) protocol is beutifily simple. Really, it is very very simple - it is a UDP packet sent from a device on your LAN to your router which can ask one of two things: (a) What is my external IP address?, and (b) Please map something to this port on my address. The latter can be TCP or UDP, and allows a suggestion of the external port to assign if possible as well as setting a timeout. The mapping has a lifetime and can be renewed. The reply says which external port was assigned.
That is it. IPv4 only, but incredibly simple for server (router) and client. Noddy in the extreme.
I love it for its simplicity - it has taken literally a few hours to implement on FireBrick. The hard part is making it so fire-walling rules can decide which mappings are allowed.
But you do have to think of security here - let's be clear: ANY DEVICE on your LAN can send a single UDP packet to allow incoming connections to ANY DEVICE on your LAN!
Yes, in theory, "third party" requests are not allowed, but the router has no way to know if a source IP (and even MAC) is spoofed on a LAN. A virus or rouge app able to send UDP packets can just open up your LAN just like that! Really, NAT is not a fire-wall!
This is why we decided to make the FireBrick allow configurable fire-wall rules to decide what mappings are allowed...
What about IPv6? Well the answer is RFC6887 PCP (Port Control Protocol) which provides some cool extra features. The main one is handling IPv6, but in theory it could talk over CGNAT as well, and allows it to do a few more things.
Firstly the "what is my external IP" has gone, in favour of "what external IP was allocated this time for this mapping". Very sensible when considering things like CGNAT which may have many external IP addresses.
It then has the two main types of request - one is to create an new incoming mapping to a port (just like NAT-PMP) but the other is to create a new explicit outgoing mapping and get confirmation that it worked, and what external IP and port have been used. The latter is easy (just send a packet) but harder to control what ports or see what ports and IP have used, so PCP solves that nicely.
It is also designed to allow for the internal and external IP and ports to match (which could just as easily apply for NAT-PMP in theory) to allow simple firewall holes to be made where there is no NAT (as is normal for IPv6, obviously). NAT is evil, after all.
It is slightly more complex, so I may code support tomorrow. Again, fire-wall rules to define what is allowed and not.
PCP allows for explicit third party mappings to be made, and suggests a gateway should not do them unless expressly told to allow them. But they are still just a UDP packet, so again ANY DEVICE on your LAN can send a single UDP packet to allow incoming connections to ANY DEVICE on your LAN!
Which is a risk, obviously.
It's all in the app!
One thing that took me a while to realise is that it is not down to the operating system of the machine or console - e.g. does Windows support NAT-PMP and/or PCP, etc. It is down to the application.
An application can send the message to open a port, simple as that. So actually it is down to which applications support these protocols.
I suspect for the likes of game consoles, where this can be important for hosting games, this may be console dependant rather than per game - I hope so. We will see :-)