RFC 5780

NAT Behavior Discovery Using Session Traversal Utilities for NAT (STUN)

πŸ“… published May 2010, from ietf

RFC 5780: NAT Behavior Discovery Using Session Traversal Utilities for NAT (STUN) πŸ¦‹

Okay bestie, this is RFC 5780 πŸ’– from the Internet Engineering Task Force (IETF). It's called NAT Behavior Discovery Using Session Traversal Utilities for NAT (STUN) ✨. The authors are D. MacDonald and B. Lowekamp, both from Skype πŸŽ€. It's in the Experimental category, its ISSN is 2070-1721, and it's dated May 2010 πŸ“…. The title block doesn't list anything this RFC obsoletes or updates 🌸.

Abstract 🌸

This spec defines an experimental way to use the Session Traversal Utilities for NAT (STUN) Protocol. It finds out whether NATs and firewalls sit between the STUN client and the STUN server, and how they currently behave πŸ‘€.

Status of This Memo πŸ“

Heads up: this document is not an Internet Standards Track spec πŸ™…β€β™€οΈ. It's published so people can examine it, implement it experimentally, and evaluate it πŸ§ͺ.

It defines an Experimental Protocol for the Internet community 🌈. It's a product of the IETF and represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) πŸ‘‘. Not every IESG-approved doc is a candidate for any level of Internet Standard, so check Section 2 of RFC 5741 if you want the details πŸ’….

For the current status, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc5780 πŸ”—.

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved πŸ”’.

This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the publication date. Please read those carefully, because they spell out your rights and restrictions πŸ“œ. Code Components pulled out of this document must include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Simplified BSD License explains πŸ’».

This doc might contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008 πŸ•°οΈ. The people who own the copyright in some of that material might not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So unless you get a proper license from those copyright holders, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process 🚫. The exceptions are formatting it for publication as an RFC or translating it into languages other than English 🌍.

Table of Contents πŸ—ΊοΈ

1.  Applicability  . . . . . . . . . . . . . . . . . . . . . . . .  4
  1.1.  Requirements Language  . . . . . . . . . . . . . . . . . .  5
2.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  6
  2.1.  Example Diagnostic Use . . . . . . . . . . . . . . . . . .  6
  2.2.  Example Use with P2P Overlays  . . . . . . . . . . . . . .  7
  2.3.  Experimental Goals . . . . . . . . . . . . . . . . . . . .  8
3.  Overview of Operations . . . . . . . . . . . . . . . . . . . .  9
  3.1.  Determining NAT Mapping  . . . . . . . . . . . . . . . . . 10
  3.2.  Determining NAT Filtering  . . . . . . . . . . . . . . . . 10
  3.3.  Binding Lifetime Discovery . . . . . . . . . . . . . . . . 10
  3.4.  Diagnosing NAT Hairpinning . . . . . . . . . . . . . . . . 11
  3.5.  Determining Fragment Handling  . . . . . . . . . . . . . . 11
  3.6.  Detecting a Generic Application Level Gateway (ALG)  . . . 11
4.  Discovery Process  . . . . . . . . . . . . . . . . . . . . . . 11
  4.1.  Source Port Selection  . . . . . . . . . . . . . . . . . . 12
  4.2.  Checking for UDP Connectivity with the STUN Server . . . . 13
  4.3.  Determining NAT Mapping Behavior . . . . . . . . . . . . . 14
  4.4.  Determining NAT Filtering Behavior . . . . . . . . . . . . 14
  4.5.  Combining and Ordering Tests . . . . . . . . . . . . . . . 15
  4.6.  Binding Lifetime Discovery . . . . . . . . . . . . . . . . 15
5.  Client Behavior  . . . . . . . . . . . . . . . . . . . . . . . 17
  5.1.  Discovery  . . . . . . . . . . . . . . . . . . . . . . . . 17
  5.2.  Security . . . . . . . . . . . . . . . . . . . . . . . . . 18
6.  Server Behavior  . . . . . . . . . . . . . . . . . . . . . . . 18
  6.1.  Preparing the Response . . . . . . . . . . . . . . . . . . 18
7.  New Attributes . . . . . . . . . . . . . . . . . . . . . . . . 20
  7.1.  Representing Transport Addresses . . . . . . . . . . . . . 21
  7.2.  CHANGE-REQUEST . . . . . . . . . . . . . . . . . . . . . . 21
  7.3.  RESPONSE-ORIGIN  . . . . . . . . . . . . . . . . . . . . . 21
  7.4.  OTHER-ADDRESS  . . . . . . . . . . . . . . . . . . . . . . 22
  7.5.  RESPONSE-PORT  . . . . . . . . . . . . . . . . . . . . . . 22
  7.6.  PADDING  . . . . . . . . . . . . . . . . . . . . . . . . . 22
8.  IAB Considerations . . . . . . . . . . . . . . . . . . . . . . 23
  8.1.  Problem Definition . . . . . . . . . . . . . . . . . . . . 23
  8.2.  Exit Strategy  . . . . . . . . . . . . . . . . . . . . . . 23
  8.3.  Brittleness Introduced by STUN NAT Behavior Discovery  . . 24
  8.4.  Requirements for a Long-Term Solution  . . . . . . . . . . 24
  8.5.  Issues with Existing NAPT Boxes  . . . . . . . . . . . . . 24
9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 25
  9.1.  STUN Attribute Registry  . . . . . . . . . . . . . . . . . 25
  9.2.  Port Numbers and SRV Registry  . . . . . . . . . . . . . . 25
10. Security Considerations  . . . . . . . . . . . . . . . . . . . 25
11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 26
12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 26
  12.1. Normative References . . . . . . . . . . . . . . . . . . . 26
  12.2. Informative References . . . . . . . . . . . . . . . . . . 27

1. Applicability ✨

Okay so this experimental NAT Behavior Discovery STUN usage tells you about a NAT device's observable transient behavior πŸ‘€. It works out how a NAT acts with respect to the STUN server being used and the particular client ports in play at the exact moment the test runs. Here's the tea 🫒: this usage does not let an app behind a NAT make an absolute determination of the NAT's characteristics. NAT devices don't behave consistently enough to predict future behavior with any guarantee πŸ’€. So if apps need reliable reach between two particular endpoints, they need to set up a communication channel through the NAT using another technique. The IETF has proposed standards, including [RFC5245] and [RFC5626], for setting up channels when a publicly accessible rendezvous service is available πŸŽ€.

The uses envisioned for the STUN attributes in this document are diagnostics and real-time tuning of apps πŸ”§. For example, it helps figure out what might work and what should be tried first, compared to more expensive methods πŸ’Έ. The attributes can also observe the behaviors that cause an app's communication to fail, which makes it easier to pick a recovery method that works 🧠. Honestly, the STUN attributes could be a basis for a network technician's diagnostics tool that watches NAT behavior too πŸ› οΈ.

This document proposes experimental use of these attributes for real-time optimization of protocol parameters in situations where a publicly accessible rendezvous service is not available 🌸. That kind of use only works when the results are applied as an optimization, and a reliable fallback is available in case the NAT's behavior becomes more restrictive than the Behavior Discovery tests determined πŸ”. One possible app is role selection in peer-to-peer (P2P) networks, based on statistical experience with establishing direct connections and diagnosing NAT behavior with a variety of peers 🧩. The experimental question is whether such a test is useful πŸ§ͺ. Picture a node that tries to join an overlay as a full peer when its NAT blocks sufficient connectivity. Joining and withdrawing from the overlay might be expensive and/or lead to unreliable or poorly performing operations 😩. Even if the behavior discovery check is only "correct" 75% of the time, its relative cheapness may make it super useful for optimizing the overlay network's behavior πŸ’…. Section 2.2 goes deeper into this experimental app and talks about how to evaluate whether it succeeds or fails πŸ”.

The apps of this STUN usage are different from the original use of STUN (originally RFC 3489 [RFC3489], now RFC 5389 [RFC5389]) πŸ¦‹. This spec admits that the information gathered in this usage is not, and cannot be, correct 100% of the time πŸ™ˆ. STUN, on the other hand, only focused on getting information that could be known to be correct and static πŸ“Œ.

This spec can also be compared to ICE πŸ‘―β€β™€οΈ. ICE requires a fallback to TURN to be available. RFC 3489 based apps, though, tried to figure out in advance whether they'd need a relay and what their peer reflexive address would be, which isn't generally achievable 😭.

This STUN usage requires an app using it to have a fallback πŸ›Ÿ. But unlike ICE's focus on the problems inherent in VoIP sessions, this usage doesn't assume it'll be used to set up a connection between a single pair of machines. So alternative fallback mechanisms may be available 🌈.

For example, in a P2P app it may be possible to simply switch out of the role where those connections need to be set up, or to pick an alternative indirect route if the peer discovers that, in practice, 10% of its connection attempts fail πŸ”„.

This is submitted to the Internet community as an experimental protocol. When it's applied with appropriate statistical underpinnings and with app behavior based on experienced connectivity patterns, it can lead to more stability and increased performance than you'd get without the knowledge it provides πŸ“ˆπŸ’–.

If a Standards Track document specifies the use of any portion of this STUN usage, that document MUST describe how incorrect information derived using these methods will be managed, either through identifying when a NAT's behavior changed or because the protocol uses such knowledge as an optimization but remains functional when the NAT's behavior changes. ⚠️ The referencing document MUST also define when the fallback mechanism will be invoked. Apps in different domains may vary greatly in how aggressively they use the fallback mechanism, so there must be a clear definition of when the fallback mechanism is invoked 🚨.

1.1. Requirements Language 🫢

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119] πŸ“–.

2. Introduction ✨

okay so "Session Traversal Utilities for NAT (STUN)" [RFC5389] already gives you a way to find your reflexive transport address toward the STUN server, using the Binding Request πŸ¦‹. this spec adds the NAT Behavior Discovery STUN usage, which lets a STUN client poke at how the NAT/firewall (NAT/FW) devices between it and the STUN server are actually behaving right now πŸ”. it defines new STUN attributes for the Binding Request and Binding Response, so it's giving upgrade πŸ’…

btw NAT/FW boxes are literally inconsistent 😭 they change how they act under load and over time. apps that need high reliability must be prepared for the NAT to get more restrictive. the vibe is that under load, NATs may switch to the most restrictive filtering and mapping behavior and shorten the lifetime of new and existing bindings. so the tea is: apps can find out how bad things are right now, but not how bad they'll get πŸ’€

that limit is real, but instant snapshots are still super useful for troubleshooting 🫢 and if you run repeated tests over time, or during known load, you can characterize a NAT's behavior. in the hands of someone who knows what the app needs and who it talks to, this is a seriously powerful tool πŸ‘‘

2.1. Example Diagnostic Use

apps that work perfectly in the lab but flop in the real world are so common in distributed systems 😩 basically every systems dev has been there, digging around trying to figure out what's different about the environment and what real-network behavior the lab missed. the Behavior Discovery usage is a powerful way to check NAT and firewall behavior while the app is running πŸ”₯ for example, an app could run Behavior Discovery tests whenever it hits significant communication problems, and then log that analysis as part of its diagnostic info πŸ“

since it's used to detect instantaneous behavior for analysis by an experienced developer or admin, there are relatively few concerns with this use πŸ’– but the user should still know that

  • adding new traffic to new destinations (STUN servers) has the potential to itself change the behavior of a NAT and
  • the user must be careful to select a STUN server that is appropriately located, ideally collocated (or even integrated) with the communication partners of the application in question, for the results to be applicable to the network conditions experienced by the application.

2.2. Example Use with P2P Overlays

okay this one is my favorite 🧚 an app could use Behavior Discovery in a P2P protocol to check whether an endpoint is a reasonable candidate to be a peer or supernode (a peer in the overlay that offers services, including message routing, to other members or clients of the overlay network) 🌸 this P2P app is willing to pick supernodes that sit behind NATs so it can skip the cost of dedicated servers. a supernode candidate needs its NAT or NATs to offer Endpoint-Independent Filtering πŸ™ˆ it might re-run tests every so often, and it would remove itself as a supernode if its NAT/FW chain lost that trait. these tests could run with other supernodes acting as STUN servers, or with dedicated STUN servers too. lowkey, many P2P algorithms are fine with non-transitive connectivity between some of their peers, so guaranteed pair-wise reliable reach might get sacrificed to spread the overlay's load across peers that most users can directly contact ✨

here's a more detailed example from a made-up P2P protocol πŸ¦‹ when P2P node A starts up, it tests its NAT(s) relative to other peers already in the overlay. if the results say A is behind a "good" NAT (with Endpoint-Independent Mapping and Filtering), A joins the overlay and connects with appropriate peers to get into the overlay's topology πŸ’… A can be reached by routing messages across the overlay, but A also tells other nodes they can reach it directly using the reflexive IP address (or addresses) it found during its initial testing.

now say later, node B wants to message A, and B isn't a neighbor of A in the overlay topology. B may send the message straight to A's IP address and start a timer ⏱️ if B doesn't get a response within a certain amount of time, it routes the message to A across the overlay instead, and it includes a flag saying a direct connection was tried but failed. (or B could send the message to A's IP address and across the overlay at the same time, which guarantees minimum response latency but can waste bandwidth πŸ™„) over time, A keeps track of the percentage of successful direct messages it gets out of the ones attempted. if that percentage is below some threshold (perhaps 75%), A may stop advertising for direct connections, because it's figured out that its NATs aren't giving reliable enough connectivity to justify the cost of trying direct messages 😀 but if the percentage is high enough, A keeps advertising, since the direct connections are making the overlay faster by cutting routing load πŸ™Œ and if A's NAT or NATs change behavior at some point, A will see its success percentage shift and may re-evaluate whether to keep advertising a public address πŸ‘€

in this example, Behavior Discovery picks A's initial operating mode, but whether A keeps advertising that public IP/port pair is based on actual operating data πŸ“Š the results are also a performance optimization, since A can always reach others through the overlay if a direct attempt fails 🫢

using Behavior Discovery for an app like this requires

  • use of a protocol capable of offering reliable end-user performance while using unreliable links between pairs of nodes.
  • a protocol offering a reliable fallback to connections attempted based on the results of Behavior Discovery probing.
  • the application is deployed behind NATs that provide Endpoint-Independent Filtering and that remain in this mode for an amount of time sufficient for the application to identify their behavior, distribute this information to the rest of the overlay, and provide useful work for the application.
this document is experimental! πŸ§ͺ apps implementing open protocols haven't been deployed in these environments yet to prove those three requirements are met. anecdotally though, NATs aimed at households and small businesses seem to have stable behavior, especially when few clients sit behind them 🏠 a bunch of P2P apps have shipped that seem to have these properties, but their protocols haven't gone through rigorous evaluation by standards bodies yet πŸŽ€

2.3. Experimental Goals

so what would count as an app successfully showing off this usage? πŸ† it would include

  • an implementation that relies on this usage to determine its run-time behavior, most likely using it to pick an initial set of options that are then adjusted based on experience with its network connections.
  • the implementation must either demonstrate its applicability in environments where it is realistic to expect a provider to deploy dedicated STUN servers with multiple IP addresses, or it must demonstrate duplicating the behavior of such a dedicated STUN server with two nodes that share the role of providing the address-changing operations required by this usage.
  • experimental evidence that the application of this usage results in improved behavior of the application in real-world conditions. the exact metrics may vary, some possibilities include: faster convergence to the proper parameters, less work to set up initial connections, fewer reconfigurations required after startup, etc.
  • a protocol specification that defines how the implementation applies this usage.

the P2P scenario above is a likely experimental test case for this usage 🌈 but other apps are possible too, obviously πŸ’œ


3. Overview of Operations πŸ—ΊοΈ

in a typical setup, a STUN client sits on a private network and reaches the public Internet through one or more NATs 🏑 the client is configured with the address of a STUN server on the public Internet. the Behavior Discovery usage uses SRV records, so a server can use a different transport address for this usage than for other usages 🧚 this usage does not provide backward compatibility with RFC 3489 [RFC3489] for either clients or servers. clients that want to be compliant with RFC 3489 servers should check out that spec πŸ“œ and servers SHOULD NOT include support for RFC 3489 clients, since the original uses of that protocol have been deprecated πŸ™…β€β™€οΈ

because STUN forbids a server from creating a new TCP or TCP/TLS connection to the client, a lot of these tests only apply to UDP 😭 the applicability of each test is indicated below.

the STUN NAT Behavior Discovery usage defines new attributes on the STUN Binding Request and STUN Binding Response, so these messages can diagnose the current behavior of the NAT(s) between the client and server πŸ”

this section is a descriptive overview of how these attributes are typically used. the normative behavior is described in Sections 5, 6, and 7 πŸ“–

3.1. Determining NAT Mapping

a client behind a NAT wants to figure out whether that NAT is currently using Endpoint-Independent, Address-Dependent, or Address and Port-Dependent Mapping [RFC4787] πŸ¦‹ it runs a series of tests that use the OTHER-ADDRESS attribute, and these tests are described in detail in Section 4 πŸ’… the tests send binding requests to the alternate address and port of the STUN server to determine the mapping behavior ✨ these tests work for UDP, TCP, or TCP/TLS connections, so no cap, they're super versatile 🫢

3.2. Determining NAT Filtering πŸ¦‹

okay so a client sitting behind a NAT wants to figure out which kind of filtering that NAT is doing right now: Endpoint-Independent, Address-Dependent, or Address and Port-Dependent Filtering [RFC4787] πŸ’…. The client runs a series of tests using the OTHER-ADDRESS and CHANGE-REQUEST attributes (we get into the details in Section 4 🧚). These tests ask for responses from the alternate address and port of the STUN server, and there's one precondition: no binding can already be established to that alternate address and port ✨.

Here's the lowkey genius part πŸ™ˆ. The NAT has no clue that the alternate address and port belong to the same server as the primary address and port, so it treats those responses exactly like it would treat them from any other host on the Internet. That means if the binding responses sent from the alternate address and port actually get through, they tell you what the NAT is currently doing: Endpoint-Independent Filtering, Address-Dependent Filtering, or Address and Port-Dependent Filtering πŸ”₯. This test only applies to UDP datagrams 🩷.

3.3. Binding Lifetime Discovery 🌸

so a lot of systems, like VoIP, need to keep a connection open between a client and a server, or between peers in a P2P system πŸ“ž. NAT bindings expire over time, so keepalive messages must be sent across the connection to keep it alive πŸ’œ. Keepalives cost some overhead on the network and on the servers though, so reducing how often you send them can be really useful 🌈.

the tricky bit is that a normal request-response protocol can't be used to test binding lifetime, because the initial request resets the binding timer 😭. That's why the RESPONSE-PORT attribute exists πŸŽ€. It lets the client and server set up a "control channel" that uses one port on the client to test the binding lifetime of a different port allocated on that same client. More generally, RESPONSE-PORT lets the client allocate two ports and ask that responses to queries sent from one port get delivered to the other πŸ¦‹. The client then uses its second port and the STUN server's alternate address to check whether an existing binding that hasn't had any traffic sent on it is still open after time T ⏰. This approach is described in detail in Section 4.6 πŸ“–. This test only applies to UDP datagrams.

3.4. Diagnosing NAT Hairpinning 🧚

STUN Binding Requests let a client find out whether it's behind a NAT that supports hairpinning of connections πŸͺž. The client first sends a Binding Request to its STUN server to learn its mapped address. Then it sends a STUN Binding Request to that mapped address, but from a different port. If the client receives its own request back, the NAT hairpins connections ✨. This test applies to UDP, TCP, or TCP/TLS connections πŸ’–.

3.5. Determining Fragment Handling 🧩

okay this one is sooo interesting πŸ€“. Some NATs act differently when they forward fragments than when they forward a single-frame datagram. For example, some NATs don't hairpin fragments at all, and some platforms throw fragments away under load πŸ’€. To diagnose this, STUN messages may be sent with the PADDING attribute, which just inserts extra space into the message πŸ“. By forcing the STUN message to be split into multiple fragments, you can watch how the NAT behaves πŸ‘€.

All of the previous tests can be performed with PADDING if the NAT's fragment behavior matters for an application. Or, if only some tests are interesting to the application, it can retest just those πŸ’…. PADDING only applies to UDP datagrams. And PADDING can not be used with RESPONSE-PORT πŸ™…β€β™€οΈ.

3.6. Detecting a Generic Application Level Gateway (ALG) πŸ•΅οΈβ€β™€οΈ

a bunch of NAT boxes on the market now try to provide "generic" ALG functionality, which is lowkey messy 😬. These generic ALGs hunt for IP addresses, whether they're written as text or stored in binary form inside a packet, and rewrite them if they match a binding. This behavior can be detected because the STUN server returns both the MAPPED-ADDRESS and the XOR-MAPPED-ADDRESS in the same response πŸ”. If the two results don't match, there's a NAT with a generic ALG somewhere in the path 🚨. This test applies to UDP and TCP, but not to TLS over TCP connections πŸ”.


4. Discovery Process πŸ”­

this section gives you a descriptive overview of how the NAT Behavior Discovery usage primitives let you run checks to discover the current behavior of the NAT (or NATs) an application is sitting behind πŸ’«. Real talk: these tests can only tell you the instantaneous behavior of a NAT, and NATs have been found to change behavior under load and over time πŸŒͺ️. So the results count as upper bounds. An application has to assume that NAT behavior can become more restrictive at any time 😀. Results from tests run on one port on the client might also not match what a different port experiences, as described in Section 4.1 🎯.

Definitions for NAT filtering and mapping behavior come from [RFC4787] πŸ“š. The tests described here cover UDP connectivity, NAT mapping behavior, NAT filtering behavior, and NAT binding lifetime discovery. More tests could be designed using this usage's mechanisms too ✨. The tests below only include ones that can be run with a client that has a single IP address. A client with multiple IP addresses (or multiple clients working together) behind the same NAT can combine their probes to test other aspects of NAT behavior, such as port overloading 🧁. This section gives a descriptive overview of how the primitives provided by the STUN attributes in this specification may be used to perform behavior tests πŸ’….

Normative specifications for the attributes are defined in later sections πŸ“œ.

4.1. Source Port Selection πŸŽ€

proper source port selection is everything for making the Behavior Discovery tests useful and accurate 😀. There are two preconditions for the tests:

  • Because mapping behavior can vary on a port-by-port basis, an application should perform its tests using the source port it intends to use, whenever possible. If it intends to use multiple source ports, it should repeat these tests for each one. Those tests should be run sequentially to reduce load on the NAT 🫢.
  • Because the results of some diagnostic checks depend on previous state in the NAT created by earlier traffic, the tests should be run using a source port that hasn't generated recent traffic. So the application should either use a random source port, or make sure no traffic has previously occurred on the selected port before running the tests. Usually that means allocating a port and holding it unused for at least 15 minutes before the tests πŸ•°οΈ.

ensuring both of these preconditions can be kinda challenging, especially for a device or application that wants to run Behavior Discovery tests at startup 😩. These guidelines are suggested for reducing the chance of problems:

  • An application meant to operate behind a NAT should not try to allocate a specific or well-known port. Software like this has to be designed to interoperate using whatever port the NAT maps it to, so a specific port isn't needed anyway πŸ™…β€β™€οΈ. Instead, on startup, a random port should be selected (see below for the recommended ranges). An application, especially on an embedded device, should not rely on the host operating system to pick the next available port, because that might result in the application getting the same port on every restart πŸ”. An application that reuses the same port between restarts may not get accurate results from Behavior Discovery tests meant to check state-related behavior of NATs, like filtering and binding lifetime 😬.
  • An application that needs multiple ports, like separate ports for control and media, should allocate those ports on startup when possible. Even if there's no immediate need for a media flow, if Behavior Discovery tests will be run on those ports, allocating them early lets them sit idle, which increases the chance of getting accurate results πŸ§˜β€β™€οΈ.
  • Getting the most reliable results means running tests with the exact ports the application will use. But in many cases an application will need to allocate and use ports without being able to run complete Behavior Discovery tests on them πŸ₯Ί. In those cases, an application should randomly select its ports from a range that's likely to get the same treatment from the NAT. This document recommends the ranges 32768-49151, which is the upper end of IANA's Registered Ports range, and 49152-65535, which is IANA's Dynamic and/or Private port range, for random selection 🌈. To try to characterize a NAT's general treatment of ports in these ranges, a small number of ports within a range can be randomly selected and characterized πŸ”.

Those tests that are especially sensitive to prior state on a NAT will be indicated below ⚠️.

4.2. Checking for UDP Connectivity with the STUN Server πŸ“‘

the client sends a STUN Binding Request to a server. This makes the server send the response back to the address and port that the request came from πŸ’Œ. If this test gets no response, the client knows right away that it doesn't have UDP connectivity with the STUN server 😡. This test only requires STUN [RFC5389] functionality 🧸.

4.3. Determining NAT Mapping Behavior πŸ—ΊοΈ

this will require at most three tests 🎯. In test I, the client performs the UDP connectivity test. The server returns its alternate address and port in OTHER-ADDRESS in the binding response. If OTHER-ADDRESS isn't returned, the server doesn't support this usage and this test can't be run πŸ™ƒ. The client examines the XOR-MAPPED-ADDRESS attribute. If this address and port are the same as the local IP address and port of the socket used to send the request, the client knows it isn't NATed, and the effective mapping will be Endpoint-Independent ✨.

In test II, the client sends a Binding Request to the alternate address, but to the primary port πŸ”. If the XOR-MAPPED-ADDRESS in the Binding Response is the same as in test I, the NAT currently has Endpoint-Independent Mapping πŸ’–. If not, test III is performed: the client sends a Binding Request to the alternate address and port πŸͺ„. If the XOR-MAPPED-ADDRESS matches test II, the NAT currently has Address-Dependent Mapping. If it doesn't match, the NAT currently has Address and Port-Dependent Mapping πŸ¦‹.

4.4. Determining NAT Filtering Behavior ✨

okay so this one also needs at most three tests bestie πŸŽ€ and they are super sensitive to whatever the NAT already remembers from earlier (prior state, iykyk 🧚).

In test I, the client does the UDP connectivity test πŸ¦‹. The server returns its alternate address and port in OTHER-ADDRESS in the binding response. If OTHER-ADDRESS isn't returned, the server doesn't support this usage and this test can't be run 😭.

In test II, the client sends a binding request to the primary address of the server with CHANGE-REQUEST set to change-port and change-IP πŸ’…. This makes the server send its response from its alternate IP address and alternate port. If the client gets a response, the NAT's current behavior is Endpoint-Independent Filtering πŸ‘‘.

If no response comes back, test III has to happen so we can tell Address-Dependent Filtering apart from Address and Port-Dependent Filtering πŸ™ˆ. In test III, the client sends a binding request to the original server address with CHANGE-REQUEST set to change-port. If the client gets a response, the current behavior is Address-Dependent Filtering. If there's no response, the current behavior is Address and Port-Dependent Filtering ✨.


4.5. Combining and Ordering Tests 🌈

clients may wish to combine and parallelize these tests to send fewer packets and speed up discovery ⚑. For example, test I of the filtering and mapping tests also checks whether UDP is blocked 🫢. Also, an application or user may not need as much detail as these sample tests give. For example, connecting nodes gets a lot harder if a NAT has any behavior other than Endpoint-Independent Mapping, which needs only test I and II of Section 4.3 πŸ’œ.

An application that finds out its NAT does not always provide Endpoint-Independent Mapping might notify the user if no relay is configured. Meanwhile, an app behind a NAT that provides Endpoint-Independent Mapping might not say anything until a connection actually fails, or it might show a less urgent notice that no relay is configured πŸ™ˆ. This kind of test doesn't replace [RFC5245] at all, but it does tell you something about whether ICE is likely to succeed at making non-relayed connections πŸ¦‹.

Care must be taken when combining and parallelizing tests 🚨. Some tests are sensitive to prior state on the NAT, and some NAT devices have an upper limit on how fast bindings can be allocated. Section 5 limits the rate at which clients may begin new STUN transactions πŸ’….


4.6. Binding Lifetime Discovery ⏳

STUN can also be used to probe how long the NAT keeps the bindings it creates 🧚. These tests are sensitive to prior state on the NAT too. For many NAT devices, an absolute refresh interval can't be determined, since bindings might be closed faster under heavy load or might not behave the way the tests suggest 😭. That's why applications that require reliable bindings must send keepalives as often as every NAT device they'll meet requires. Suggested refresh intervals are outside the scope of this document. [RFC5245] and OUTBOUND [RFC5626] have suggested refresh intervals πŸŽ€.

Figuring out the binding lifetime depends on using two separate source ports to send STUN Binding Requests to the STUN server πŸ¦‹. The general idea is that the client uses source port X to send one Binding Request. After a while in which source port X isn't used, the client uses a second source port, Y, to send a Binding Request to the STUN server that says the response should go to the binding established on port X. If the binding for port X has timed out, that response won't come back. By changing the time between the first request from X and the follow-up from Y, the client can work out the binding lifetime 🌸.

Here's the step-by-step. The client first sends a Binding Request to the server from a particular source port, X. This creates a binding in the NAT. The response from the server contains a MAPPED-ADDRESS attribute, which gives the public address and port on the NAT. Call these Pa and Pp, respectively. The client then starts a timer with a value of T seconds. When that timer fires, the client sends another Binding Request to the server, using the same destination address and port but a different source port, Y. This request contains a RESPONSE-PORT attribute set to Pp, asking for the response to be delivered to (Pa, Pp). That creates a new binding on the NAT and makes the STUN server send a Binding Response that would match the old binding, (Pa, Pp), if it still exists πŸ’–. If the client gets the Binding Response on port X, it knows the binding hasn't expired. If the client gets the Binding Response on port Y (which can happen if the old binding expired and the NAT gave the same public address and port to the new binding), or gets no response at all, it knows the binding has expired πŸ™ˆ.

Some NATs only refresh bindings when outbound traffic is sent, so the client must resend a binding request from the original source port before starting a second test with a different value of T πŸ”₯. The client can find the binding lifetime by doing a binary search through T. Eventually it lands on the value where no response comes back for any timer greater than T, but a response does come back for any timer less than T πŸ‘‘. The binding refresh behavior (outbound only or all traffic) can also be figured out by sending multiple Binding Requests from port Y without refreshing from the original source port X 🧚.

This discovery process takes quite a bit of time, so it's usually run in the background on a device once it boots πŸ’….

Results can be inconsistent from one run to the next 😭. For example, if the NAT reboots or gets reset for some reason, the process may find a lifetime shorter than the real one. Binding lifetime can also depend on how much traffic the NAT is handling. For this reason, implementations are encouraged to run the test many times and be ready for inconsistent results 🫢.

Like the other diagnostics, this test is inherently unstable πŸ’€. In particular, an overloaded NAT might shorten binding lifetimes to shed load. A client might find this diagnostic useful at startup. For example, it could set the initial keepalive interval on its connection to the server to 10 seconds while it runs this check 🌈. After the current lifetime is determined, the keepalive interval used by the connection to the server can be set to that appropriate value. Later checks of the binding lifetime can then use the keepalives on the server connection πŸ¦‹. The STUN Keepalive Usage [RFC5626] gives a response that confirms the connection is open and lets the client check that its mapped address hasn't changed πŸ’œ. Since that does both the keepalive job and the diagnostic job, it should be preferred over any attempt to characterize the connection with a secondary technique ✨.


5. Client Behavior πŸ’…

Unless otherwise specified here, all procedures for preparing, sending, and processing messages described in the STUN Binding Usage [RFC5389] are followed πŸŽ€.

Because support for RESPONSE-PORT is optional, a client MUST be prepared to receive a 420 (Unknown Attribute) error to requests that include RESPONSE-PORT 😭. Support for OTHER-ADDRESS and CHANGE-REQUEST is optional, but MUST be supported by servers advertised via SRV, as described below. This lets PADDING and RESPONSE-PORT be used in applications where servers don't have multiple IP addresses 🧚. Clients MUST be prepared to receive a 420 for requests that include CHANGE-REQUEST when OTHER-ADDRESS was not received in Binding Response messages from the server πŸ™ˆ.

If an application uses the NAT Behavior Discovery STUN usage by multiplexing it in a flow with application traffic, a FINGERPRINT attribute SHOULD be included, unless it's always possible to tell a STUN message from an application message based on their header πŸ”₯.

When PADDING is used, it SHOULD be equal to the MTU of the outgoing interface πŸ¦‹.

Clients SHOULD ignore an ALTERNATE-SERVER attribute in a response, unless they're using authentication with a provider of STUN servers that is aware of the topology requirements of the tests being performed πŸ’–.

A client SHOULD NOT generate more than ten new STUN transactions per second, and SHOULD pace them so the retransmission timeouts (RTOs) don't synchronize the retransmissions of each transaction 🌸.


5.1. Discovery πŸ”

Unless the user or application already knows the transport address of a STUN server supporting the NAT Behavior Discovery usage through other means, a client is configured with the domain name of the provider of the STUN servers πŸŽ€. The domain is resolved to a transport address using SRV procedures [RFC2782]. How the client gets configured with the domain name of the STUN servers, or acquires a specific transport address, is out of scope for this document 🌈.

For the Behavior Discovery usage, the service name is stun-behavior for UDP and TCP. The service name is stun-behaviors for TLS over TCP. Only tcp is defined as a protocol for stun-behaviors πŸ’…. Other aspects of handling failures and default ports follow what's described in STUN [RFC5389] ✨.


5.2. Security πŸ”

Servers MAY require authentication before letting a client use their services. How to get those credentials, if the server requires them, is outside the scope of this usage 🧚. Presumably, the administrator or application relying on this usage should have its own method for getting credentials πŸ’œ. If the client receives a 401 (Unauthorized) Response to a Request, then it must either get the appropriate credential from the application before retrying, or report a permanent failure 😭. Procedures for encoding the MESSAGE-INTEGRITY attribute for a request are described in STUN [RFC5389] 🫢.


6. Server Behavior πŸ–₯️

Unless otherwise specified here, all procedures for preparing, sending, and processing messages described for the STUN Binding Usage of STUN [RFC5389] are followed πŸŽ€.

A server implementing the NAT Behavior Discovery usage SHOULD be configured with two separate IP addresses on the public Internet 🌸. On startup, the server SHOULD allocate a pair of ports for each of the UDP, TCP, and TCP/TLS transport protocols, so it can send and receive datagrams using the same ports on each IP address (normally a wildcard binding does this) πŸ”₯. TCP and TCP/TLS MUST use different ports πŸ™ˆ. If a server can't allocate the same ports on two different IP addresses, then it MUST NOT include an OTHER-ADDRESS attribute in any Response, and it MUST respond with a 420 (Unknown Attribute) to any Request with a CHANGE-REQUEST attribute πŸ’€. A server with only one IP address MUST NOT be advertised using the SRV service name stun-behavior or stun-behaviors 😭🫢

6.1. Preparing the Response πŸŽ€

okay so once the server finishes all the authentication and verification stuff βœ…, it only starts the Usage-specific processing if the Binding Request has any of the attributes defined in this document: RESPONSE-PORT, CHANGE-REQUEST, or PADDING. If the request has none of those, OTHER-ADDRESS and RESPONSE-ORIGIN still get included in the Binding Response, bestie 🫢

The server MUST include both MAPPED-ADDRESS and XOR-MAPPED-ADDRESS in its Response. no cap, this is non-negotiable πŸ’…

If the Request has the CHANGE-REQUEST attribute but the server doesn't have an alternate address and port (like we talked about above), the server MUST generate an error response of type 420. πŸ’€

The source address and port of the Binding Response depend on the value of CHANGE-REQUEST and on the address and port the Binding Request arrived on. Table 1 breaks it all down, and it's honestly so clean πŸ¦‹

Let A1 and A2 be the two IP addresses the server uses, and let P1 and P2 be the ports it uses. Let Da be the destination IP address of the Binding Request (it'll be either A1 or A2), and let Dp be the destination port of the Binding Request (it'll be either P1 or P2). Let Ca be the other address, so if Da is A1 then Ca is A2, and if Da is A2 then Ca is A1. Similarly, let Cp be the other port, so if Dp is P1 then Cp is P2, and if Dp is P2 then Cp is P1. 🧚

Now the flag rules, bestie. If the "change port" flag is set in CHANGE-REQUEST and the "change IP" flag is not, the source IP address of the Binding Response MUST be Da and the source port MUST be Cp. If the "change IP" flag is set and the "change port" flag is not, the source IP address MUST be Ca and the source port MUST be Dp. When both flags are set, the source IP address MUST be Ca and the source port MUST be Cp. And if neither flag is set, or CHANGE-REQUEST is absent entirely, the source IP address MUST be Da and the source port MUST be Dp. The whole thing is a vibe check, and the server is always on theirs 😭

+--------------------+----------------+-------------+---------------+
| Flags              | Source Address | Source Port | OTHER-ADDRESS |
+--------------------+----------------+-------------+---------------+
| none               | Da             | Dp          | Ca:Cp         |
| Change IP          | Ca             | Dp          | Ca:Cp         |
| Change port        | Da             | Cp          | Ca:Cp         |
| Change IP and      | Ca             | Cp          | Ca:Cp         |
| Change port        |                |             |               |
+--------------------+----------------+-------------+---------------+

     Table 1: Impact of Flags on Packet Source and OTHER-ADDRESS

The server MUST add a RESPONSE-ORIGIN attribute to the Binding Response, containing the source address and port used to send the Binding Response. It's like the server signing its own work πŸ–ŠοΈβœ¨

If the server supports an alternate address and port, the server MUST add an OTHER-ADDRESS attribute to the Binding Response. This holds the source IP address and port that would be used if the client had set the "change IP" and "change port" flags in the Binding Request. As Table 1 shows, those are Ca and Cp, respectively, no matter what the CHANGE-REQUEST flags are set to πŸ“

If the Request contained a PADDING attribute, PADDING MUST be included in the Binding Response. The server SHOULD use a PADDING length equal to the MTU on the outgoing interface, rounded up to an even multiple of four bytes. And if the Request also contains the RESPONSE-PORT attribute, the server MUST return an error response of type 400. the way that this is giving "you can't have it both ways" πŸ™ˆ

Following that, the server finishes the rest of the processing from STUN [RFC5389]. If authentication is being required, the server MUST include a MESSAGE-INTEGRITY attribute and associated attributes as appropriate. A FINGERPRINT attribute is only required if the STUN messages are being multiplexed with application traffic that needs a FINGERPRINT to tell STUN messages apart πŸ”₯

An ALTERNATE-SERVER attribute MUST NOT be included with any other attribute defined in this specification. 🚫

When the server sends the Response, it goes out from the source address we figured out above and gets sent to the source address of the Request. If RESPONSE-PORT is present, the server sends the response to that port instead of the originating port. ✈️


7. New Attributes ✨

This document defines several STUN attributes that are needed for NAT Behavior Discovery. These attributes are all used only with Binding Requests and Binding Responses. CHANGE-REQUEST was originally defined in RFC 3489 [RFC3489], but it's redefined here because that document is obsoleted by [RFC5389]. πŸ“š

  Comprehension-required range (0x0000-0x7FFF):
    0x0003: CHANGE-REQUEST
    0x0026: PADDING
    0x0027: RESPONSE-PORT

  Comprehension-optional range (0x8000-0xFFFF):
    0x802b: RESPONSE-ORIGIN
    0x802c: OTHER-ADDRESS

7.1. Representing Transport Addresses πŸ¦‹

Whenever an attribute contains a transport IP address and port, it has the same format as MAPPED-ADDRESS. Similarly, the XOR- attributes have the same format as XOR-MAPPED-ADDRESS [RFC5389]. it's all about consistency, babe πŸ’–

7.2. CHANGE-REQUEST πŸŽ€

The CHANGE-REQUEST attribute carries two flags that control the IP address and port the server uses to send the response. These flags are called the "change IP" and "change port" flags. CHANGE-REQUEST is only allowed in the Binding Request, and it's optional there too. The flags are super useful for figuring out a NAT's current filtering behavior, since they tell the server to send the Binding Responses from the alternate source IP address and/or alternate port. 🌸

The attribute is 32 bits long, but only two bits (A and B) are actually used:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A B 0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here's what the flags mean:

  • A: this is the "change IP" flag. If it's true, it asks the server to send the Binding Response with a different IP address than the one the Binding Request was received on. 🌍
  • B: this is the "change port" flag. If it's true, it asks the server to send the Binding Response with a different port than the one the Binding Request was received on. πŸ”Œ

7.3. RESPONSE-ORIGIN πŸ”

The RESPONSE-ORIGIN attribute gets inserted by the server, and it tells you the source IP address and port the response was sent from. It's really handy for spotting double NAT setups πŸ‘€ It only shows up in Binding Responses, periodt.

7.4. OTHER-ADDRESS ✨

OTHER-ADDRESS shows up in Binding Responses. It tells the client the source IP address and port that would be used if the client had asked for the "change IP" and "change port" behavior. OTHER-ADDRESS MUST NOT be inserted into a Binding Response unless the server has a second IP address. no second IP, no OTHER-ADDRESS, the end πŸ™…β€β™€οΈ

OTHER-ADDRESS uses the same attribute number as CHANGED-ADDRESS from RFC 3489 [RFC3489], because it's basically the same thing with a new name. It got renamed so the function is clearer. the glow-up is real πŸ’…

7.5. RESPONSE-PORT 🧚

The RESPONSE-PORT attribute carries a port. It can be in the Binding Request, and it tells the server which port the Binding Response should go to. For servers that support RESPONSE-PORT, the Binding Response MUST be sent to the source IP address of the Binding Request and the port in RESPONSE-PORT. It's used in tests such as Section 4.6. When it's not present, the server sends the Binding Response to the source IP address and port of the Binding Request. The server MUST NOT process a request that contains both a RESPONSE-PORT and a PADDING attribute, bestie, that's a hard no 🚫 The RESPONSE-PORT attribute is optional in the Binding Request, and server support for it is optional too.

RESPONSE-PORT is a 16-bit unsigned integer in network byte order, followed by 2 bytes of padding. Allowable values of RESPONSE-PORT are 0-65536. πŸ“

7.6. PADDING 🌈

The PADDING attribute lets the whole message be padded so that the STUN message gets split into IP fragments. PADDING is made up entirely of a free-form string, and its value doesn't matter. PADDING can show up in either Binding Requests or Binding Responses. 🧩

PADDING MUST NOT be longer than the length that brings the total IP datagram size to 64K. It SHOULD be equal in length to the MTU of the outgoing interface, rounded up to an even multiple of four bytes. Because STUN messages with PADDING are meant to test how UDP fragments behave, they're the exception to the usual rule that STUN messages stay under the MTU of the path. this is the one time being huge is the whole point 😭🫢


8. IAB Considerations 🌸

The IAB has studied the problem of "Unilateral Self-Address Fixing" (UNSAF). That's the general process where a client tries to figure out its address in another realm on the far side of a NAT, using a collaborative protocol reflection mechanism [RFC3424]. The STUN NAT Behavior Discovery usage is an example of a protocol that does this kind of job. The IAB has said that any protocol developed for this purpose has to document a specific set of considerations, and this section does exactly that πŸ“‹βœ¨

8.1. Problem Definition 🎯

Per RFC 3424 [RFC3424], any UNSAF proposal has to provide a precise definition of a specific, limited-scope problem that the proposal solves. A short-term fix shouldn't get stretched to solve other problems, because those generalizations keep the supposed short-term fix around for way longer, and then it's no longer accurate to call it "short term" πŸ˜…

The specific problem the STUN NAT Behavior Discovery usage solves is letting a client, which might be sitting behind a NAT of any type, work out the instantaneous characteristics of that NAT. That lets you either diagnose what's causing problems for this app or other apps, or change how an application behaves based on the NAT's current behavior and a suitable statistical model of what the app needs to succeed. πŸ”πŸ’–

8.2. Exit Strategy πŸšͺ

RFC 3424 also says any UNSAF proposal has to describe an exit strategy or transition plan. The better short-term fixes are the ones that naturally get used less and less as the right technology gets deployed. 🌱

The STUN NAT Behavior Discovery usage doesn't provide an exit strategy for v4 NATs by itself. As of this writing, it looks like some sort of NAT will be necessary between v6 clients and v4 servers. This specification won't be needed for those v6-to-v4 NATs, because the IETF is planning to describe how they work. And this specification won't be of any interest for v6-to-v6 connectivity πŸ§šβ€β™€οΈ

8.3. Brittleness Introduced by STUN NAT Behavior Discovery πŸ¦‹

okay so the IAB rules for UNSAF proposals (from [RFC3424]) want you to talk about what might make systems more "brittle" πŸ₯Ί

From [RFC3424], any UNSAF proposal must provide:

   Discussion of specific issues that may render systems more
   "brittle".  For example, approaches that involve using data at
   multiple network layers create more dependencies, increase
   debugging challenges, and make it harder to transition.

STUN NAT Behavior Discovery lets a client figure out how a NAT is currently behaving πŸ‘€ That info is super useful for a developer or network admin working outside an app, so it can also help them diagnose the brittleness another app is dealing with. Inside an app, it lets the app adjust itself to match what the NAT is doing right now ✨

This document is experimental πŸ§ͺ bc it's unclear how much brittleness gets added to an app that relies on Behavior Discovery, and the people designing that protocol have to evaluate it carefully. 🫢 The experiment basically asks one question: can an app get less brittle by using behavior-discovery info, compared to trying to use the network with zero awareness of the NATs its traffic has to cross? πŸ’…

8.4. Requirements for a Long-Term Solution 🌸

Same deal, the IAB wants (from [RFC3424]):

From [RFC3424], any UNSAF proposal must provide:

   Identify requirements for longer-term, sound technical solutions
   -- contribute to the process of finding the right longer-term
   solution.

As long as v4 NATs are still around, we're gonna need ways to adapt to them 🫠 As mentioned above, well-behaved v6 to v4 NATs and direct v6 to v6 connections won't need behavior characterization. 🧚

8.5. Issues with Existing NAPT Boxes πŸ’œ

Still quoting the IAB rules from [RFC3424]:

From [RFC3424], any UNSAF proposal must provide:

   Discussion of the impact of the noted practical issues with
   existing deployed NATs and experience reports.

This usage gives you a set of generic attributes you can stitch together to test loads of NAT behaviors πŸŽ€ It describes tests for the most commonly known NAT box behaviors, but the BEHAVE mailing list keeps surfacing new ones, and some of those might not be easy to detect with the tests in here. Still, the techniques can be mixed and matched to test NAT behaviors nobody knows about yet πŸ”₯

9. IANA Considerations πŸ“‹

9.1. STUN Attribute Registry πŸ“

This spec defines several new STUN attributes, and IANA has added them to the "STUN Attributes" registry ✨

0x0003: CHANGE-REQUEST
0x0027: RESPONSE-PORT
0x0026: PADDING
0x8027: CACHE-TIMEOUT
0x802b: RESPONSE-ORIGIN
0x802c: OTHER-ADDRESS

9.2. Port Numbers and SRV Registry 🌈

By default, STUN NAT Behavior Discovery runs on the same ports as STUN: 3478 over UDP and TCP, and 5349 for TCP over TLS. πŸ’– It does get its own SRV names though: "stun-behavior" for UDP and TCP, and "stun-behaviors" for TLS. Either the SRV procedures or the ALTERNATE-SERVER procedures can be used to run Behavior Discovery on a different port, and those are subject to the recommendations in Section 5. 🧚

This spec defines the "stun-behavior" and "stun-behaviors" SRV service names. "stun-behavior" can be used with the SRV protocol specifiers "udp" and "tcp". "stun-behaviors" can only be specified with "tcp". 🫢 So the allowable SRV queries are:

_stun-behavior._udp            UDP
_stun-behavior._tcp            TCP
_stun-behaviors._tcp           TLS over TCP

10. Security Considerations πŸ”

This usage inherits the security considerations of STUN [RFC5389] 🫣 It also adds several new attributes, and their security considerations are detailed right here.

OTHER-ADDRESS doesn't open up any new attacks πŸ™…β€β™€οΈ It's another spot where an attacker could pretend to be a STUN server, but that's not a very interesting attack. If an attacker is in a position to tamper with the Binding Response, they can completely hide the STUN server from the client. πŸ‘€

  • Requests containing both RESPONSE-PORT and PADDING are rejected by the server. This prevents an amplification attack that is targeted at the originating address. πŸ›‘

The only attack possible with the PADDING attribute is sending a huge padding length to make a server allocate a huge chunk of memory 😱 Servers ignore any padding length greater than 64K, so the scope of that attack is limited. In general, servers should not allocate more memory than the size of the received datagram. This attack would only affect non-compliant implementations. πŸ’€

RESPONSE-ORIGIN and RESPONSE-PORT don't give anyone any additional attacks ✨

11. Acknowledgements 🫢

The authors want to thank the authors of the original STUN specification [RFC3489], since a lot of the ideas, attributes, and descriptions in this doc came from there πŸ’œ Thanks also to Dan Wing, Cullen Jennings, and Magnus Westerlund for their detailed comments 🌸

12. References πŸ“š

12.1. Normative References 🌟

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2782]  Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for
           specifying the location of services (DNS SRV)", RFC 2782,
           February 2000.

[RFC4787]  Audet, F. and C. Jennings, "Network Address Translation
           (NAT) Behavioral Requirements for Unicast UDP", BCP 127,
           RFC 4787, January 2007.

[RFC5389]  Rosenberg, J., Mahy, R., Matthews, P., and D. Wing,
           "Session Traversal Utilities for NAT (STUN)", RFC 5389,
           October 2008.

12.2. Informative References πŸ¦‹

[RFC3424]  Daigle, L. and IAB, "IAB Considerations for UNilateral
           Self-Address Fixing (UNSAF) Across Network Address
           Translation", RFC 3424, November 2002.

[RFC3489]  Rosenberg, J., Weinberger, J., Huitema, C., and R. Mahy,
           "STUN - Simple Traversal of User Datagram Protocol (UDP)
           Through Network Address Translators (NATs)", RFC 3489,
           March 2003.

[RFC5245]  Rosenberg, J., "Interactive Connectivity Establishment
           (ICE): A Protocol for Network Address Translator (NAT)
           Traversal for Offer/Answer Protocols", RFC 5245,
           April 2010.

[RFC5626]  Jennings, C., Mahy, R., and F. Audet, "Managing Client-
           Initiated Connections in the Session Initiation Protocol
           (SIP)", RFC 5626, October 2009.

Authors' Addresses πŸ’Œ

Derek C. MacDonald
Skype
Palo Alto, CA
USA

EMail: derek.macdonald@gmail.com


Bruce B. Lowekamp
Skype
Palo Alto, CA
USA

EMail: bbl@lowekamp.net

That's the whole spec, bestie!! 🌈✨ Thanks for hanging with me through all 6 parts πŸ«ΆπŸ’…

πŸ“¦ where this page comes from