I started reading RFC 5389, the STUN protocol, and as a matter of fact, in response to your Request for Comments, I do have a Comment or two. It goes like this: Holy cow, that's probably the most spectacularly overdesigned trivial protocol I've ever seen.
What STUN actually does is receive a UDP packet from a client, then tell the client what his external IP address is (in case he's behind a NAT). How could that be hard, you ask?
Well, they have whole sections about how to heuristically guess whether a particular packet is STUN or not, when you have multiple protocols multiplexed on the same port. As if there was some kind of port number shortage.
Also, they have a 12-bit method id and a 2-bit class id, formatted like this: mm:mmmC:mmmC:mmmm. Yes, that's right, the class id is two bits scattered in the middle of the method id. But that's okay, because there's only one method, namely #1. Yes. And (2^12)-1 reserved method numbers, just in case.
Not to be outdone, the TR-069 standards people made STUN mandatory, so the server can send the client a UDP message telling it to please initiate a new TCP session back to the (not behind a NAT) server. Ok, makes sense. But what goes in the UDP message, you ask? Why, it's a full HTTP/1.1 request jammed in a UDP packet, with an URL path, a query string, three URL parameters, and a few headers, including a timestamp (which must be strictly increasing), a random id, a nonce, and an authenticator calculated from all of the above using an md5 checksum. All to make sure nobody can forge a "please check in with the server" request, which, in terms of information content, is literally zero bytes long. And don't get me started about their need for a timestamp, a random id, and a nonce.