==> do we want to test for the presence of a proto-41 forwarding
NAT box? That would likely be complicated (would require extra
transmission of proto-41 packets)? If we put that in, it's a
"may" at most.
I hadn't thought of that... Is it the case that if proto-41
forwarding is in place then the communication would be
un-differentiable from a non nated one?
It's slightly different: the "internal IP address" set in the packets
to detect whether NAT was on the path or not would tell there is a
NAT, and would result in (an unnecessary) fallback to UDP.
So, to cater for that situation, the logic would have to be like:
1) send the packet to the server with "my own address" set
2) the server notices that "my own address" and the source address
are not the same.
2.1) the server tries to send an IP-proto-41 packet to the source
address in any case; if it doesn't hear back soon, retry with
UDP.
2.2) failing that, just send the packet on UDP.
2.3) in both cases, activate the NAT keepalive sequence.
It seems to me that the fallback in 2.1) might add some substantial
code in case the NAT doesn't forward proto-41, especially if the
negotiation/parameter exchange would otherwise conclude after sending
the packet (i.e., this would require at least 1.5 roundtrips to verify
a host behind a NAT got the information, and if it didn't, at least 2
roundtrips -- using just UDP could be done with 1 roundtrip.)
Obviously, this kind of "forwarder detection check" could possibly be
implemented separately, and would be indicated as a flag from the
client, but that might have some minor failure modes as well.