RFC 5389

Session Traversal Utilities for NAT (STUN)

๐Ÿ“… published October 2008, from ietf

RFC 5389: Session Traversal Utilities for NAT (STUN) ๐ŸŽ€

okay bestie, let's start with the paperwork ๐Ÿ“‹โœจ this is RFC 5389, a Standards Track doc from October 2008. it came from the Network Working Group and the authors are J. Rosenberg (Cisco), R. Mahy (no affiliation listed), P. Matthews (Unaffiliated), and D. Wing (Cisco). it obsoletes RFC 3489 ๐Ÿ’… and there's no "Updates" line, so it doesn't update anything else.


Status of This Memo ๐Ÿ“œ

so this doc is an Internet standards track protocol for the Internet community, and it's basically asking everyone to talk about it and suggest fixes ๐Ÿ—ฃ๏ธ if you want the official standardization state, go check the "Internet Official Protocol Standards" (STD 1) list. and yes, distribution is totally unlimited ๐ŸŒˆ


Abstract ๐Ÿฆ‹

okay so STUN (Session Traversal Utilities for NAT) is a protocol that helps other protocols deal with Network Address Translator (NAT) traversal ๐Ÿ’– an endpoint can use it to figure out the IP address and port a NAT gave it ๐Ÿ—บ๏ธ it can also check whether two endpoints can actually reach each other, and it can act as a keep-alive to keep NAT bindings from dying ๐Ÿซถ the best part? it works with lots of existing NATs and doesn't need them to do anything special ๐Ÿ”ฅ

STUN is not a complete NAT traversal solution by itself! ๐Ÿšซ it's a tool you use inside a traversal solution. this is a big change from the last version (RFC 3489), which pitched STUN as the whole package ๐Ÿ™ˆ

Table of Contents ๐Ÿงš

1. Introduction ....................................................4
2. Evolution from RFC 3489 .........................................4
3. Overview of Operation ...........................................5
4. Terminology .....................................................8
5. Definitions .....................................................8
6. STUN Message Structure .........................................10
7. Base Protocol Procedures .......................................12
   7.1. Forming a Request or an Indication ........................12
   7.2. Sending the Request or Indication .........................13

        7.2.1. Sending over UDP ...................................13
        7.2.2. Sending over TCP or TLS-over-TCP ...................14
   7.3. Receiving a STUN Message ..................................16
        7.3.1. Processing a Request ...............................17
               7.3.1.1. Forming a Success or Error Response .......18
               7.3.1.2. Sending the Success or Error Response .....19
        7.3.2. Processing an Indication ...........................19
        7.3.3. Processing a Success Response ......................19
        7.3.4. Processing an Error Response .......................20
8. FINGERPRINT Mechanism ..........................................20
9. DNS Discovery of a Server ......................................21
10. Authentication and Message-Integrity Mechanisms ...............22
   10.1. Short-Term Credential Mechanism ..........................22
        10.1.1. Forming a Request or Indication ...................23
        10.1.2. Receiving a Request or Indication .................23
        10.1.3. Receiving a Response ..............................24
   10.2. Long-Term Credential Mechanism ...........................24
        10.2.1. Forming a Request .................................25
               10.2.1.1. First Request ............................25
               10.2.1.2. Subsequent Requests ......................26
        10.2.2. Receiving a Request ...............................26
        10.2.3. Receiving a Response ..............................27
11. ALTERNATE-SERVER Mechanism ....................................28
12. Backwards Compatibility with RFC 3489 .........................28
   12.1. Changes to Client Processing .............................29
   12.2. Changes to Server Processing .............................29
13. Basic Server Behavior .........................................30
14. STUN Usages ...................................................30
15. STUN Attributes ...............................................31
   15.1. MAPPED-ADDRESS ...........................................32
   15.2. XOR-MAPPED-ADDRESS .......................................33
   15.3. USERNAME .................................................34
   15.4. MESSAGE-INTEGRITY ........................................34
   15.5. FINGERPRINT ..............................................36
   15.6. ERROR-CODE ...............................................36
   15.7. REALM ....................................................38
   15.8. NONCE ....................................................38
   15.9. UNKNOWN-ATTRIBUTES .......................................38
   15.10. SOFTWARE ................................................39
   15.11. ALTERNATE-SERVER ........................................39
16. Security Considerations .......................................39
   16.1. Attacks against the Protocol .............................39
        16.1.1. Outside Attacks ...................................39
        16.1.2. Inside Attacks ....................................40
   16.2. Attacks Affecting the Usage ..............................40
        16.2.1. Attack I: Distributed DoS (DDoS) against a
                Target ............................................41
        16.2.2. Attack II: Silencing a Client .....................41
        16.2.3. Attack III: Assuming the Identity of a Client .....42
        16.2.4. Attack IV: Eavesdropping ..........................42
   16.3. Hash Agility Plan ........................................42
17. IAB Considerations ............................................42
18. IANA Considerations ...........................................43
   18.1. STUN Methods Registry ....................................43
   18.2. STUN Attribute Registry ..................................43
   18.3. STUN Error Code Registry .................................44
   18.4. STUN UDP and TCP Port Numbers ............................45
19. Changes since RFC 3489 ........................................45
20. Contributors ..................................................47
21. Acknowledgements ..............................................47
22. References ....................................................47
   22.1. Normative References .....................................47
   22.2. Informative References ...................................48
Appendix A. C Snippet to Determine STUN Message Types .............50

1. Introduction ๐ŸŒธ

okay so this spec is all about Session Traversal Utilities for NAT, which is basically a toolkit for dealing with NATs ๐Ÿงฐ it lets an endpoint find out the IP address and port a NAT assigned to its private IP address and port ๐Ÿ‘€ it also gives endpoints a way to keep a NAT binding alive โญ with some extensions, it can do connectivity checks between two endpoints [MMUSIC-ICE], or relay packets between them [BEHAVE-TURN] ๐Ÿ’…

since it's a tool, it's built to be extended ๐Ÿ”ง this spec defines an extensible packet format, works over several transport protocols, and gives you two forms of authentication ๐Ÿ”

STUN is meant to be used in the context of one or more NAT traversal solutions, and those solutions are called STUN usages ๐ŸŽ€ each usage explains how STUN gets used to actually traverse the NAT. usually that means it spells out when STUN messages get sent, which optional attributes to include, what server to use, and which authentication mechanism to use ๐Ÿ“‹ Interactive Connectivity Establishment (ICE) [MMUSIC-ICE] is one usage, and SIP Outbound [SIP-OUTBOUND] is another ๐Ÿฆ‹ sometimes a usage needs extensions to STUN, which can take the form of new methods, attributes, or error response codes ๐Ÿงฉ you can find more about usages in Section 14 ๐Ÿซถ


2. Evolution from RFC 3489 ๐Ÿ’–

okay, history time ๐Ÿ“œ STUN was first defined in RFC 3489 [RFC3489]. that spec, which people call "classic STUN," pitched itself as a complete fix for the NAT traversal problem ๐Ÿ˜ค the idea was that a client would figure out whether it was behind a NAT, work out its NAT type, discover its IP address and port on the public side of the outermost NAT, and then use that address and port inside protocols like the Session Initiation Protocol (SIP) [RFC3261] ๐Ÿ’…

but here's the tea โ˜• experience since RFC 3489 showed that classic STUN just doesn't work well enough to be deployed as a solution ๐Ÿ’€ the address and port it learned were sometimes fine for talking to a peer and sometimes not ๐Ÿ™ƒ classic STUN had no way to tell whether they'd actually work, and no fix when they didn't. on top of that, its NAT classification algorithm turned out to be faulty, since lots of NATs didn't fit neatly into the types it defined ๐Ÿ™ˆ

classic STUN also had a security hole ๐Ÿšจ attackers could feed the client wrong mapped addresses under certain topologies and constraints, and that couldn't be solved with any cryptographic means โŒ that problem is still here in this spec, but those attacks are now mitigated by more complete solutions that use STUN ๐Ÿ›ก๏ธ

so for all these reasons, this spec obsoletes RFC 3489 and instead describes STUN as a tool that's used as part of a complete NAT traversal solution ๐Ÿฆ‹ ICE [MMUSIC-ICE] is a complete solution for protocols built on the offer/answer [RFC3264] model, like SIP โœจ SIP Outbound [SIP-OUTBOUND] is a complete solution for traversing SIP signaling, and it uses STUN in a very different way ๐ŸŒˆ it's technically possible for a protocol to use STUN by itself (classic STUN) as a traversal solution, but that usage isn't described here, and it's strongly discouraged for the reasons above ๐Ÿšซ

the on-the-wire protocol only changed a little from classic STUN ๐ŸŽ€ it now runs over TCP as well as UDP, and extensibility got added in a more structured way ๐Ÿงฉ a magic cookie mechanism was added for demultiplexing STUN from application protocols, and it was done by stealing 32 bits from the 128-bit transaction ID that RFC 3489 defined, which keeps the change backwards compatible ๐Ÿ“ mapped addresses are now encoded with a new exclusive-or format ๐Ÿ”ฅ there are other, smaller changes too, and Section 19 has the full list ๐Ÿ“‹

and yes, the name changed too ๐Ÿ’… STUN used to be "Simple Traversal of UDP through NAT," but since the scope changed, it's now "Session Traversal Utilities for NAT." the acronym is still STUN, which is honestly all anyone ever remembers anyway ๐Ÿ˜ญ๐Ÿซถ

3. Overview of Operation โœจ

okay so this section is descriptive only, bestie, which means it's the big-picture tour and not the rulebook ๐ŸŽ€

Here's the setup ๐Ÿ‘‡

                               /-----\
                             // STUN  \\
                            |   Server  |
                             \\       //
                               \-----/




                          +--------------+             Public Internet
          ................|     NAT 2    |.......................
                          +--------------+



                          +--------------+             Private NET 2
          ................|     NAT 1    |.......................
                          +--------------+




                              /-----\
                            //  STUN \\
                           |    Client |
                            \\       //               Private NET 1
                              \-----/

Figure 1: One Possible STUN Configuration

So one possible STUN setup is shown in Figure 1 ๐Ÿฆ‹ There are two entities (called STUN agents) that speak the STUN protocol. The lower agent is the client, and it's sitting on private network 1. That network connects to private network 2 through NAT 1, and private network 2 connects to the public Internet through NAT 2. The upper agent is the server, and it lives on the public Internet ๐ŸŒธ

STUN is a client-server protocol, and it supports two types of transactions ๐Ÿ’– The first is a request/response transaction, where a client sends a request to a server and the server sends back a response. The second is an indication transaction, where either agent (client or server) sends an indication and nobody replies. Both types include a transaction ID, which is a randomly selected 96-bit number. For request/response transactions, the transaction ID lets the client match the response to the request that made it. For indications, the transaction ID is just a debugging aid ๐Ÿ”

Every STUN message starts with a fixed header that has a method, a class, and the transaction ID โœจ The method tells you which request or indication this is. This specification only defines one method, Binding, but other methods are expected to show up in other documents ๐Ÿงš The class tells you whether the message is a request, a success response, an error response, or an indication. After the fixed header come zero or more attributes. These are Type-Length-Value extensions that carry extra info for that specific message ๐Ÿ’…

This document defines a single method called Binding, and it can be used in request/response transactions or in indication transactions ๐ŸŒˆ When it's used in request/response transactions, Binding can figure out the particular "binding" a NAT has allocated to a STUN client. When it's used in either kind of transaction, Binding can also keep those "bindings" alive ๐Ÿซถ

Now the Binding request/response flow, which is lowkey my favourite part ๐Ÿ˜ญ A Binding request is sent from a STUN client to a STUN server. By the time it reaches the server, it may have gone through one or more NATs between the two (in Figure 1, there were two such NATs). Each time the request passes through a NAT, that NAT rewrites the source transport address (the source IP address and source port) of the packet. So the source transport address the server receives is the public IP address and port created by the NAT closest to the server. This is called a reflexive transport address ๐Ÿฆ‹ The server then copies that source transport address into an XOR-MAPPED-ADDRESS attribute in the Binding response and sends the response back to the client. On the way back through a NAT, the NAT changes the destination transport address in the IP header, but the transport address inside the XOR-MAPPED-ADDRESS attribute stays untouched. That's the trick! The client can learn its reflexive transport address as allocated by the outermost NAT with respect to the STUN server ๐ŸŽ€

Next up, multiplexing ๐Ÿ“ In some usages, STUN has to share a port with other protocols (for example, [MMUSIC-ICE] and [SIP-OUTBOUND]). In those cases, there has to be a way to look at a packet and tell whether it's a STUN packet or not. STUN gives you three fields in the STUN header with fixed values for exactly this job. If those aren't enough, STUN packets can also carry a FINGERPRINT value, which can further help tell packets apart ๐Ÿ’œ

STUN also defines a set of optional procedures that a usage can decide to use, called mechanisms โญ These include DNS discovery, a redirection technique to an alternate server, a fingerprint attribute for demultiplexing, and two authentication and message-integrity exchanges. The authentication mechanisms revolve around a username, a password, and a message-integrity value. This specification defines two of them: the long-term credential mechanism and the short-term credential mechanism. Each usage gets to specify which mechanisms are allowed with that usage ๐Ÿ‘‘

In the long-term credential mechanism, the client and server share a pre-provisioned username and password. They do a digest challenge/response exchange that's inspired by the one defined for HTTP [RFC2617], although it differs in the details ๐Ÿ’… In the short-term credential mechanism, the client and server swap a username and password through some out-of-band method before the STUN exchange even starts. For example, in the ICE usage [MMUSIC-ICE], the two endpoints use out-of-band signaling to exchange a username and password ๐ŸŒธ Those are then used to integrity protect and authenticate the request and response. There's no challenge or nonce involved in this one ๐Ÿงš


4. Terminology โœจ

Okay, quick vocab check ๐ŸŽ€ In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in BCP 14, RFC 2119 [RFC2119], and they indicate requirement levels for compliant STUN implementations ๐Ÿ’–


5. Definitions ๐Ÿฆ‹

Time to learn the lingo, bestie ๐Ÿ’… Here's the glossary ๐Ÿ‘‡

  • STUN Agent: A STUN agent is an entity that implements the STUN protocol. The entity can be either a STUN client or a STUN server โœจ
  • STUN Client: A STUN client is an entity that sends STUN requests and receives STUN responses. A STUN client can also send indications. In this specification, the terms STUN client and client are synonymous ๐ŸŽ€
  • STUN Server: A STUN server is an entity that receives STUN requests and sends STUN responses. A STUN server can also send indications. In this specification, the terms STUN server and server are synonymous ๐ŸŒธ
  • Transport Address: The combination of an IP address and port number (such as a UDP or TCP port number) ๐Ÿงš
  • Reflexive Transport Address: A transport address learned by a client that identifies that client as seen by another host on an IP network, typically a STUN server. When there is an intervening NAT between the client and the other host, the reflexive transport address represents the mapped address allocated to the client on the public side of the NAT. Reflexive transport addresses are learned from the mapped address attribute (MAPPED-ADDRESS or XOR-MAPPED-ADDRESS) in STUN responses ๐Ÿฆ‹
  • Mapped Address: Same meaning as reflexive address. This term is retained only for historic reasons and due to the naming of the MAPPED-ADDRESS and XOR-MAPPED-ADDRESS attributes ๐Ÿ’œ
  • Long-Term Credential: A username and associated password that represent a shared secret between client and server. Long-term credentials are generally granted to the client when a subscriber enrolls in a service and persist until the subscriber leaves the service or explicitly changes the credential ๐Ÿ‘‘
  • Long-Term Password: The password from a long-term credential ๐Ÿ“
  • Short-Term Credential: A temporary username and associated password that represent a shared secret between client and server. Short-term credentials are obtained through some kind of protocol mechanism between the client and server, preceding the STUN exchange. A short-term credential has an explicit temporal scope, which may be based on a specific amount of time (such as 5 minutes) or on an event (such as termination of a SIP dialog). The specific scope of a short-term credential is defined by the application usage ๐ŸŒˆ
  • Short-Term Password: The password component of a short-term credential โญ
  • STUN Indication: A STUN message that does not receive a response ๐Ÿ’…
  • Attribute: The STUN term for a Type-Length-Value (TLV) object that can be added to a STUN message. Attributes are divided into two types: comprehension-required and comprehension-optional. STUN agents can safely ignore comprehension-optional attributes they don't understand, but cannot successfully process a message if it contains comprehension-required attributes that are not understood ๐Ÿซถ
  • RTO: Retransmission TimeOut, which defines the initial period of time between transmission of a request and the first retransmit of that request โœจ

6. STUN Message Structure โœจ

okay bestie, let's talk about what a STUN message actually looks like ๐ŸŽ€ STUN messages are encoded in binary using a network-oriented format, which means most significant byte or octet first. People also call that big-endian ๐Ÿ’… The transmission order gets the full breakdown in Appendix B of RFC 791 [RFC0791] if you want the deep dive. Unless we say otherwise, numbers are in decimal (base 10) ๐Ÿ”ข

All STUN messages MUST start with a 20-byte header followed by zero or more Attributes ๐Ÿ’– The header holds the STUN message type, the magic cookie, the transaction ID, and the message length โœจ

    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|     STUN Message Type     |         Message Length        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         Magic Cookie                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   |                     Transaction ID (96 bits)                  |
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              Figure 2: Format of STUN Message Header

The most significant 2 bits of every STUN message MUST be zeroes ๐Ÿ™ˆ This is what lets you tell STUN packets apart from other protocols when STUN is multiplexed with them on the same port ๐Ÿซถ

The message type tells you the message class (request, success response, failure response, or indication) and the message method (the primary function) ๐Ÿฆ‹ There are four message classes, but there are only two types of transactions in STUN: request/response transactions (a request message plus a response message) and indication transactions (a single indication message) ๐Ÿ’œ Response classes are split into error and success responses so the STUN message gets processed faster ๐Ÿƒโ€โ™€๏ธ

The message type field breaks down like this:

                    0                 1
                    2  3  4 5 6 7 8 9 0 1 2 3 4 5

                   +--+--+-+-+-+-+-+-+-+-+-+-+-+-+
                   |M |M |M|M|M|C|M|M|M|C|M|M|M|M|
                   |11|10|9|8|7|1|6|5|4|0|3|2|1|0|
                   +--+--+-+-+-+-+-+-+-+-+-+-+-+-+

            Figure 3: Format of STUN Message Type Field

Here the bits in the message type field are shown as most significant (M11) through least significant (M0) ๐Ÿงฉ M11 through M0 represent a 12-bit encoding of the method, and C1 and C0 represent a 2-bit encoding of the class. A class of 0b00 is a request, 0b01 is an indication, 0b10 is a success response, and 0b11 is an error response ๐ŸŒˆ This spec defines a single method, Binding. The method and class are orthogonal, so for each method, a request, success response, error response, and indication are all possible ๐Ÿ‘‘ Extensions that define new methods MUST indicate which classes are permitted for that method ๐Ÿ“

For example, a Binding request has class=0b00 (request) and method=0b000000000001 (Binding), and it gets encoded into the first 16 bits as 0x0001 ๐ŸŽ€ A Binding response has class=0b10 (success response) and method=0b000000000001, and it gets encoded into the first 16 bits as 0x0101 ๐Ÿฆ‹

Note: This unfortunate encoding is due to assignment of values in [RFC3489] that did not consider encoding Indications, Success, and Errors using bit fields. ๐Ÿ’€

The magic cookie field MUST contain the fixed value 0x2112A442 in network byte order ๐Ÿ“ In RFC 3489 [RFC3489], this field was part of the transaction ID. Putting the magic cookie here lets a server detect whether the client will understand certain attributes that were added in this revised specification โœจ It also helps tell STUN packets apart from packets of other protocols when STUN shares a port with them ๐Ÿซถ

The transaction ID is a 96-bit identifier used to uniquely identify STUN transactions ๐Ÿ”‘ For request/response transactions, the STUN client picks the transaction ID for the request, and the server echoes it back in the response. For indications, the agent sending the indication picks it ๐Ÿงš It mainly correlates requests with responses, though it also plays a small role in helping to prevent certain types of attacks ๐Ÿ›ก๏ธ The server uses the transaction ID as a key to identify each transaction uniquely across all clients ๐ŸŒธ So the transaction ID MUST be uniformly and randomly chosen from the interval 0 .. 2**96-1, and it SHOULD be cryptographically random ๐ŸŽฒ Resends of the same request reuse the same transaction ID. The client MUST choose a new transaction ID for new transactions, unless the new request is bit-wise identical to the previous request and sent from the same transport address to the same IP address ๐Ÿ™…โ€โ™€๏ธ Success and error responses MUST carry the same transaction ID as their corresponding request ๐Ÿ’… When an agent is acting as a STUN server and a STUN client on the same port, the transaction IDs in requests the agent sends have no relationship to the transaction IDs in requests it receives ๐Ÿ”„

The message length MUST contain the size, in bytes, of the message, not including the 20-byte STUN header ๐Ÿ“ Since all STUN attributes are padded to a multiple of 4 bytes, the last 2 bits of this field are always zero ๐Ÿ˜Œ That's another way to tell STUN packets apart from other protocols ๐Ÿ’œ

After the fixed header portion come zero or more attributes ๐ŸŽ Each attribute is TLV (Type-Length-Value) encoded. The details of the encoding, and of the attributes themselves, are in Section 15 ๐Ÿ“š


7. Base Protocol Procedures ๐Ÿงš

this section is the core playbook for STUN ๐Ÿ“– It defines the base procedures: how messages get formed, how they get sent, and how they get processed when they arrive. It also spells out the detailed processing for the Binding method ๐Ÿ’– Other sections describe optional procedures a usage may choose to use in certain situations ๐ŸŒท And other documents may define other extensions to STUN by adding new methods, new attributes, or new error response codes ๐Ÿฆ‹

7.1. Forming a Request or an Indication

when you're making a request or indication, the agent MUST follow the rules in Section 6 when creating the header ๐ŸŽ€ On top of that, the message class MUST be either "Request" or "Indication" (whichever fits), and the method must be either Binding or some method defined in another document ๐Ÿ”ฅ

Then the agent adds any attributes the method or the usage specifies ๐Ÿง For example, some usages may tell the agent to use an authentication method (Section 10) or the FINGERPRINT attribute (Section 8) ๐Ÿ”

If the agent is sending a request, it SHOULD add a SOFTWARE attribute to the request โœจ Agents MAY include a SOFTWARE attribute in indications, depending on the method. Extensions to STUN should discuss whether SOFTWARE is useful in new indications ๐Ÿซง

For the Binding method with no authentication, no attributes are required unless the usage says otherwise ๐ŸŒธ

All STUN messages sent over UDP SHOULD be less than the path MTU, if it's known ๐Ÿ“ฆ If the path MTU is unknown, messages SHOULD be the smaller of 576 bytes and the first-hop MTU for IPv4 [RFC1122], and 1280 bytes for IPv6 [RFC2460]. This value corresponds to the overall size of the IP packet ๐ŸŒ So for IPv4, the actual STUN message would need to be less than 548 bytes (576 minus the 20-byte IP header, minus the 8-byte UDP header, assuming no IP options are used) ๐Ÿงฎ

STUN has no way to handle the case where the request fits under the MTU but the response would be larger than the MTU ๐Ÿ˜ฌ It's not expected to be an issue for STUN, though ๐Ÿ’… The MTU limitation is a SHOULD and not a MUST, to account for cases where STUN itself is being used to probe MTU characteristics [BEHAVE-NAT] ๐Ÿ” Outside of this or similar applications, the MTU constraint MUST be followed ๐Ÿšซ

7.2. Sending the Request or Indication

next up, the agent sends the request or indication ๐Ÿš€ This document specifies how to send STUN messages over UDP, TCP, or TLS-over-TCP. Other transport protocols may be added in the future ๐ŸŒŠ The STUN usage must specify which transport protocol is used and how the agent figures out the IP address and port of the recipient ๐Ÿ—บ๏ธ Section 9 describes a DNS-based method for finding the IP address and port of a server, which a usage may choose to use ๐Ÿงญ STUN may be used with anycast addresses, but only with UDP and in usages where authentication is not used ๐Ÿ“ก

At any time, a client MAY have multiple outstanding STUN requests with the same STUN server (multiple transactions in progress, each with a different transaction ID) ๐ŸŽ€ Unless other limits on the rate of new transactions apply (like the ones ICE sets for connectivity checks, or when STUN runs over TCP), a client SHOULD space new transactions to a server by RTO, and SHOULD limit itself to ten outstanding transactions to the same server ๐Ÿซถ pacing is everything, bestie โณ

7.2.1. Sending over UDP โœจ

Okay bestie, when STUN runs over UDP, the message can totally get dropped by the network ๐Ÿ˜ญ. So reliability for request/response transactions comes from the client resending its own request ๐Ÿ”. STUN indications are not retransmitted, which means indication transactions over UDP are not reliable ๐Ÿฅบ.

A client SHOULD retransmit a STUN request message starting with an interval of RTO ("Retransmission TimeOut"), doubling after each retransmission. RTO is an estimate of the round-trip time (RTT), and it's computed as described in RFC 2988 [RFC2988], with two exceptions ๐Ÿ’…. First, the initial value for RTO SHOULD be configurable (rather than the 3 s recommended in RFC 2988) and SHOULD be greater than 500 ms. The exception cases for this "SHOULD" are when other mechanisms are used to derive congestion thresholds (such as the ones defined in ICE for fixed rate streams), or when STUN is used in non-Internet environments with known network capacities. On fixed-line access links, a value of 500 ms is RECOMMENDED ๐ŸŒธ. Second, the value of RTO SHOULD NOT be rounded up to the nearest second. Instead, a 1 ms accuracy SHOULD be maintained โฑ๏ธ. As with TCP, the usage of Karn's algorithm is RECOMMENDED [KARN87]. When applied to STUN, that means RTT estimates SHOULD NOT be computed from STUN transactions that result in the retransmission of a request ๐Ÿ™ˆ.

The value for RTO SHOULD be cached by a client after the transaction completes, and used as the starting value for RTO for the next transaction to the same server (based on equality of IP address) ๐Ÿงš. The value SHOULD be considered stale and discarded after 10 minutes ๐Ÿ•.

Retransmissions continue until a response is received, or until a total of Rc requests have been sent. Rc SHOULD be configurable and SHOULD have a default of 7. If, after the last request, a duration equal to Rm times the RTO has passed without a response (giving ample time to get a response if only this final request actually succeeds), the client SHOULD consider the transaction to have failed. Rm SHOULD be configurable and SHOULD have a default of 16. A STUN transaction over UDP is also considered failed if there has been a hard ICMP error [RFC1122] ๐Ÿ’€. For example, assuming an RTO of 500 ms, requests would be sent at times 0 ms, 500 ms, 1500 ms, 3500 ms, 7500 ms, 15500 ms, and 31500 ms. If the client has not received a response after 39500 ms, the client will consider the transaction to have timed out โฐ.


7.2.2. Sending over TCP or TLS-over-TCP ๐ŸŽ€

For TCP and TLS-over-TCP, the client opens a TCP connection to the server ๐Ÿ”Œ.

In some usages of STUN, STUN is sent as the only protocol over the TCP connection. In that case, it can be sent without any additional framing or demultiplexing. In other usages, or with other extensions, it may be multiplexed with other data over a TCP connection. When that happens, STUN MUST be run on top of some kind of framing protocol, specified by the usage or extension, which lets the agent extract complete STUN messages and complete application layer messages ๐Ÿ“ฆ. The STUN service running on the well-known port or ports discovered through the DNS procedures in Section 9 is for STUN alone, not for STUN multiplexed with other data. So no framing protocols are used in connections to those servers. When additional framing is used, the usage will specify how the client knows to apply it and what port to connect to. For example, for ICE connectivity checks, this information is learned through out-of-band negotiation between client and server ๐Ÿค.

When STUN is run by itself over TLS-over-TCP, the TLS_RSA_WITH_AES_128_CBC_SHA ciphersuite MUST be implemented at a minimum. Implementations MAY also support any other ciphersuite ๐Ÿ”. When it receives the TLS Certificate message, the client SHOULD verify the certificate and inspect the site identified by the certificate. If the certificate is invalid or revoked, or if it does not identify the appropriate party, the client MUST NOT send the STUN message or otherwise proceed with the STUN transaction ๐Ÿšซ. The client MUST verify the identity of the server. To do that, it follows the identification procedures defined in Section 3.1 of RFC 2818 [RFC2818]. Those procedures assume the client is dereferencing a URI. For purposes of this specification, the client treats the domain name or IP address used in Section 8.1 as the host portion of the URI that has been dereferenced. Alternatively, a client MAY be configured with a set of domains or IP addresses that are trusted. If a certificate is received that identifies one of those domains or IP addresses, the client considers the identity of the server to be verified ๐Ÿซง.

When STUN is run multiplexed with other protocols over a TLS-over-TCP connection, the mandatory ciphersuites and TLS handling procedures operate as defined by those protocols ๐Ÿ’œ.

Reliability of STUN over TCP and TLS-over-TCP is handled by TCP itself, so there are no retransmissions at the STUN protocol level. However, for a request/response transaction, if the client has not received a response by Ti seconds after it sent the SYN to establish the connection, it considers the transaction to have timed out. Ti SHOULD be configurable and SHOULD have a default of 39.5s. This value was chosen to equalize the TCP and UDP timeouts for the default initial RTO ๐Ÿงฎ.

In addition, if the client is unable to establish the TCP connection, or the TCP connection is reset or fails before a response is received, any request/response transaction in progress is considered to have failed ๐Ÿ’”.

The client MAY send multiple transactions over a single TCP (or TLS-over-TCP) connection, and it MAY send another request before receiving a response to the previous one. The client SHOULD keep the connection open until it:

  • has no further STUN requests or indications to send over that connection, and
  • has no plans to use any resources (such as a mapped address (MAPPED-ADDRESS or XOR-MAPPED-ADDRESS) or relayed address [BEHAVE-TURN]) that were learned through STUN requests sent over that connection, and
  • if multiplexing other application protocols over that port, has finished using that other application, and
  • if using that learned port with a remote peer, has established communications with that remote peer, as is required by some TCP NAT traversal techniques (e.g., [MMUSIC-ICE-TCP]).

At the server end, the server SHOULD keep the connection open and let the client close it, unless the server has determined that the connection has timed out (for example, due to the client disconnecting from the network). Bindings learned by the client will remain valid in intervening NATs only while the connection remains open. Only the client knows how long it needs the binding โณ. The server SHOULD NOT close a connection if a request was received over that connection for which a response was not sent. A server MUST NOT ever open a connection back towards the client in order to send a response ๐Ÿ™…โ€โ™€๏ธ. Servers SHOULD follow best practices regarding connection management in cases of overload ๐Ÿšฆ.


7.3. Receiving a STUN Message ๐Ÿ“ฌ

This section specifies how a STUN message gets processed. The processing here is for STUN messages as defined in this specification. Additional rules for backwards compatibility are defined in Section 12. Those additional procedures are optional, and usages can elect to use them. First, a set of processing operations is applied that is independent of the class. That's followed by class-specific processing, described in the subsections that follow ๐Ÿ—‚๏ธ.

When a STUN agent receives a STUN message, it first checks that the message obeys the rules of Section 6. It checks that the first two bits are 0, that the magic cookie field has the correct value, that the message length is sensible, and that the method value is a supported method. It checks that the message class is allowed for the particular method. If the message class is "Success Response" or "Error Response", the agent checks that the transaction ID matches a transaction that is still in progress. If the FINGERPRINT extension is being used, the agent checks that the FINGERPRINT attribute is present and contains the correct value. If any errors are detected, the message is silently discarded ๐Ÿคซ. When STUN is being multiplexed with another protocol, an error may indicate that this is not really a STUN message. In that case, the agent should try to parse the message as a different protocol.

The STUN agent then does any checks required by an authentication mechanism that the usage has specified (see Section 10) ๐Ÿ”‘.

Once the authentication checks are done, the STUN agent checks for unknown attributes and known-but-unexpected attributes in the message. Unknown comprehension-optional attributes MUST be ignored by the agent. Known-but-unexpected attributes SHOULD be ignored by the agent. Unknown comprehension-required attributes cause processing that depends on the message class, which is described below ๐Ÿ‘€.

At this point, further processing depends on the message class of the request.


7.3.1. Processing a Request ๐Ÿง 

If the request contains one or more unknown comprehension-required attributes, the server replies with an error response with an error code of 420 (Unknown Attribute), and includes an UNKNOWN-ATTRIBUTES attribute in the response that lists the unknown comprehension-required attributes ๐Ÿ™ƒ.

The server then does any additional checking that the method or the specific usage requires. If all the checks succeed, the server formulates a success response as described below โœ….

When run over UDP, a request received by the server could be the first request of a transaction, or a retransmission. The server MUST respond to retransmissions such that the following property is preserved: if the client receives the response to the retransmission and not the response that was sent to the original request, the overall state on the client and server is identical to the case where only the response to the original retransmission is received, or where both responses are received (in which case the client will use the first one). The easiest way to meet this requirement is for the server to remember all transaction IDs received over UDP and their corresponding responses in the last 40 seconds. However, this requires the server to hold state, and will be inappropriate for any requests which are not authenticated ๐Ÿ—ƒ๏ธ. Another way is to reprocess the request and recompute the response. The latter technique MUST only be applied to requests that are idempotent (a request is considered idempotent when the same request can be safely repeated without impacting the overall state of the system) and result in the same success response for the same request. The Binding method is considered to be idempotent ๐Ÿ”. Note that there are certain rare network events that could cause the reflexive transport address value to change, resulting in a different mapped address in different success responses ๐ŸŒช๏ธ. Extensions to STUN MUST discuss the implications of request retransmissions on servers that do not store transaction state ๐Ÿ“.

7.3.1.1. Forming a Success or Error Response โœจ

okay so when the server is forming the response (success or error), it follows the rules in Section 6 ๐ŸŽ€ the method of the response is the same as the request's method, and the message class is either "Success Response" or "Error Response" ๐Ÿ’–

for an error response, the server MUST add an ERROR-CODE attribute containing the error code from the processing above ๐Ÿšจ the reason phrase isn't fixed, but it SHOULD be something that fits the error code ๐Ÿ’… some errors also bring extra attributes along for the ride, and those get spelled out wherever that error code is defined โœจ like, for error code 420 (Unknown Attribute), the server MUST include an UNKNOWN-ATTRIBUTES attribute ๐Ÿ™ˆ certain authentication errors add attributes too (see Section 10) ๐Ÿ” and extensions are allowed to define other errors and/or extra attributes to add in error cases ๐Ÿงš

if the server authenticated the request with an authentication mechanism, then the server SHOULD add the matching authentication attributes to the response (see Section 10) ๐Ÿซถ

the server also adds whatever attributes the specific method or usage requires ๐ŸŒˆ and on top of that, the server SHOULD add a SOFTWARE attribute to the message ๐Ÿ’œ

for the Binding method, no extra checking is needed unless the usage says otherwise ๐Ÿฆ‹ when forming the success response, the server adds an XOR-MAPPED-ADDRESS attribute, and its contents are the source transport address of the request message ๐Ÿ˜ญ for UDP, that's the source IP address and source UDP port of the request message ๐ŸŒธ for TCP and TLS-over-TCP, it's the source IP address and source TCP port of the TCP connection as the server sees it ๐Ÿ‘‘

7.3.1.2. Sending the Success or Error Response ๐Ÿ’Œ

the response (success or error) goes back over the same transport the request came in on ๐Ÿ” if the request arrived over UDP, the response's destination IP address and port are the source IP address and port of the received request message, and the response's source IP address and port are equal to the destination IP address and port of the received request message ๐Ÿฆ‹ if the request arrived over TCP or TLS-over-TCP, the response goes back on that same TCP connection ๐ŸŽ€

7.3.2. Processing an Indication ๐Ÿ”

if the indication has unknown comprehension-required attributes, the indication gets discarded and processing stops ๐Ÿ›‘

then the agent does any extra checking the method or the specific usage needs ๐Ÿ“‹ if all the checks pass, the agent processes the indication โœ… no response is generated for an indication, bestie ๐Ÿ™…โ€โ™€๏ธ

for the Binding method, no extra checking or processing is needed unless the usage says otherwise ๐ŸŒท just getting the message is enough to refresh the "bindings" in the intervening NATs โœจ it's giving "I exist, so I'm refreshing you" ๐Ÿ’…

since indications are NOT re-transmitted over UDP (unlike requests), the sending agent doesn't need to handle re-transmissions of indications ๐Ÿ™Œ

7.3.3. Processing a Success Response ๐Ÿฅฐ

if the success response has unknown comprehension-required attributes, the response gets discarded and the transaction is considered to have failed ๐Ÿ’€

then the client does any extra checking the method or the specific usage requires โœ”๏ธ if all the checks succeed, the client processes the success response ๐ŸŽ‰

for the Binding method, the client checks that the XOR-MAPPED-ADDRESS attribute is present in the response ๐Ÿ”Ž it also checks the address family specified ๐Ÿงญ if the address family is unsupported, the attribute SHOULD be ignored ๐Ÿ™ˆ if it's an unexpected but supported address family (for example, the Binding transaction was sent over IPv4, but the address family specified is IPv6), then the client MAY accept and use the value ๐ŸŒˆ

7.3.4. Processing an Error Response ๐Ÿ˜ฌ

if the error response has unknown comprehension-required attributes, or if it doesn't contain an ERROR-CODE attribute, then the transaction is simply considered to have failed ๐Ÿ’”

then the client does any processing the authentication mechanism specifies (see Section 10) ๐Ÿ” this might result in a new transaction attempt ๐Ÿ”

the processing at this point depends on the error code, the method, and the usage ๐Ÿง  here are the default rules:

  • if the error code is 300 through 399, the client SHOULD consider the transaction as failed unless the ALTERNATE-SERVER extension is being used ๐Ÿงš see Section 11 ๐ŸŒธ
  • if the error code is 400 through 499, the client declares the transaction failed ๐Ÿšซ in the case of 420 (Unknown Attribute), the response should contain an UNKNOWN-ATTRIBUTES attribute that gives more info ๐Ÿ”
  • if the error code is 500 through 599, the client MAY resend the request ๐Ÿ”„ clients that do so MUST limit the number of times they do this ๐Ÿ›‘ boundaries, bestie ๐Ÿ’–

any other error code causes the client to consider the transaction failed ๐Ÿ™ƒ


8. FINGERPRINT Mechanism โœจ

this section describes an optional mechanism for STUN that helps tell STUN messages apart from packets of other protocols when the two are multiplexed on the same transport address ๐Ÿ•ต๏ธโ€โ™€๏ธ this mechanism is optional, and a STUN usage must describe if and when it's used ๐Ÿ“ the FINGERPRINT mechanism is NOT backwards compatible with RFC 3489, so it can't be used in environments where that compatibility is required ๐Ÿšซ

in some usages, STUN messages are multiplexed on the same transport address as other protocols, like the Real Time Transport Protocol (RTP) ๐ŸŽถ to apply the processing described in Section 7, STUN messages must first be separated from the application packets ๐Ÿงบ

Section 6 describes three fixed fields in the STUN header that can be used for this purpose ๐ŸŽ€ but in some cases, those three fixed fields might not be enough ๐Ÿ˜…

when the FINGERPRINT extension is used, an agent includes the FINGERPRINT attribute in the messages it sends to another agent ๐Ÿ’Œ Section 15.5 describes where that attribute goes and what its value is ๐Ÿ“ when an agent receives what it believes is a STUN message, then, in addition to other basic checks, it also checks that the message contains a FINGERPRINT attribute and that the attribute has the correct value ๐Ÿ” Section 7.3 describes when the FINGERPRINT check happens in the overall processing of a STUN message โฐ this extra check helps the agent catch messages of other protocols that might otherwise look like STUN messages ๐Ÿงšโ€โ™€๏ธ

9. DNS Discovery of a Server ๐Ÿ—บ๏ธ

this section describes an optional procedure for STUN that lets a client use DNS to figure out the IP address and port of a server ๐ŸŒ a STUN usage must describe if and when this extension is used ๐Ÿ“ to use this procedure, the client must know a server's domain name and a service name, and the usage must also describe how the client gets those ๐Ÿ”‘ hard-coding the server's domain name into software is NOT RECOMMENDED, in case the domain name gets lost or needs to change for legal or other reasons ๐Ÿ˜ญ

when a client wants to find a STUN server on the public Internet that accepts Binding request/response transactions, the SRV service name is "stun" ๐ŸŒŸ when it wants a STUN server that accepts Binding request/response transactions over a TLS session, the SRV service name is "stuns" ๐Ÿ”’ STUN usages MAY define additional DNS SRV service names ๐Ÿ’œ

the domain name is resolved to a transport address using the SRV procedures specified in [RFC2782] ๐Ÿงญ the DNS SRV service name is the service name provided as input to this procedure ๐ŸŽฏ the protocol in the SRV lookup is the transport protocol the client will run STUN over: "udp" for UDP and "tcp" for TCP ๐Ÿ›ค๏ธ note that only "tcp" is defined with "stuns" at this time ๐Ÿ“Œ

the procedures of RFC 2782 are followed to determine which server to contact ๐Ÿง  RFC 2782 spells out how a set of SRV records gets sorted and then tried ๐Ÿ“‹ however, RFC 2782 only says the client should "try to connect to the (protocol, address, service)" without giving any details on what happens if that fails ๐Ÿคทโ€โ™€๏ธ so when following these procedures, if the STUN transaction times out without receiving a response, the client SHOULD retry the request to the next server in the ordered defined by RFC 2782 ๐Ÿ” such a retry is only possible for request/response transmissions, since indication transactions generate no response or timeout ๐Ÿ™…โ€โ™€๏ธ

the default port for STUN requests is 3478, for both TCP and UDP ๐ŸŽ€

administrators of STUN servers SHOULD use this port in their SRV records for UDP and TCP ๐Ÿ“‡ in all cases, the port in DNS MUST reflect the one the server is actually listening on ๐Ÿ‘€ the default port for STUN over TLS is 5349 ๐Ÿ” servers can run STUN over TLS on the same port as STUN over TCP if the server software supports determining whether the initial message is a TLS or STUN message ๐Ÿงฉ

if no SRV records were found, the client does an A or AAAA record lookup of the domain name ๐Ÿ” the result will be a list of IP addresses, each of which can be contacted at the default port using UDP or TCP, regardless of the STUN usage ๐ŸŒˆ for usages that require TLS, the client connects to one of those IP addresses using the default STUN over TLS port ๐Ÿ”’

10. Authentication and Message-Integrity Mechanisms ๐Ÿ”

this section defines two mechanisms for STUN that a client and server can use to provide authentication and message integrity ๐Ÿ’– they're known as the short-term credential mechanism and the long-term credential mechanism ๐Ÿง both are optional, and each usage must specify if and when they're used ๐Ÿ“ because of that, clients and servers will both know which mechanism (if any) to follow, based on which usage applies ๐Ÿง  for example, a STUN server on the public Internet supporting ICE would have no authentication, whereas the STUN server functionality in an agent supporting connectivity checks would use short-term credentials ๐Ÿฆ‹ an overview of these two mechanisms is in Section 3 โœจ

each mechanism specifies the extra processing needed to use it, extending the processing in Section 7 ๐Ÿ› ๏ธ that additional processing happens in three different places: when forming a message, when receiving a message right after the basic checks have been performed, and when doing the detailed processing of error responses ๐Ÿ—‚๏ธ

10.1. Short-Term Credential Mechanism ๐ŸŽ€

the short-term credential mechanism assumes that, before the STUN transaction, the client and server have already used some other protocol to swap a credential in the form of a username and password ๐Ÿค this credential is time-limited, and the time limit is defined by the usage โณ

as an example, in the ICE usage [MMUSIC-ICE], the two endpoints use out-of-band signaling to agree on a username and password, and that username and password apply for the duration of the media session ๐ŸŽถ

this credential is used to form a message-integrity check in each request and in many responses ๐Ÿ’… there's no challenge and response like in the long-term mechanism ๐Ÿ™…โ€โ™€๏ธ so replay is prevented by virtue of the time-limited nature of the credential ๐Ÿ”ฅ

10.1.1. Forming a Request or Indication ๐Ÿ’Œ

okay so for a request or indication, the agent MUST include the USERNAME and MESSAGE-INTEGRITY attributes in the message ๐Ÿซถ. The HMAC for MESSAGE-INTEGRITY gets computed the way Section 15.4 describes โœจ. Also, bestie, the password is never included in the request or indication ๐Ÿ”๐Ÿ™ˆ

10.1.2. Receiving a Request or Indication ๐Ÿ“ฌ

After the agent finishes the basic processing of a message, it runs the checks below in the order listed ๐Ÿง

  • If the message does not contain both a MESSAGE-INTEGRITY and a USERNAME attribute:
    • If the message is a request, the server MUST reject the request with an error response. This response MUST use an error code of 400 (Bad Request).
    • If the message is an indication, the agent MUST silently discard the indication.
  • If the USERNAME does not contain a username value currently valid within the server:
    • If the message is a request, the server MUST reject the request with an error response. This response MUST use an error code of 401 (Unauthorized).
    • If the message is an indication, the agent MUST silently discard the indication.
  • Using the password associated with the username, compute the value for the message integrity as described in Section 15.4. If the resulting value does not match the contents of the MESSAGE-INTEGRITY attribute:
    • If the message is a request, the server MUST reject the request with an error response. This response MUST use an error code of 401 (Unauthorized).
    • If the message is an indication, the agent MUST silently discard the indication.

If these checks pass, the agent keeps processing the request or indication โœ…. Any response generated by a server MUST include the MESSAGE-INTEGRITY attribute, computed using the password utilized to authenticate the request. The response MUST NOT contain the USERNAME attribute.

If any of the checks fail, a server MUST NOT include a MESSAGE-INTEGRITY or USERNAME attribute in the error response. This is because, in these failure cases, the server cannot determine the shared secret necessary to compute MESSAGE-INTEGRITY ๐Ÿฅ€

10.1.3. Receiving a Response ๐Ÿ“ฉ

The client looks for the MESSAGE-INTEGRITY attribute in the response. If it's there, the client computes the message integrity over the response as defined in Section 15.4, using the same password it used for the request. If the resulting value matches the contents of the MESSAGE-INTEGRITY attribute, the response is considered authenticated ๐Ÿ”’. If the value doesn't match, or if MESSAGE-INTEGRITY was absent, the response MUST be discarded, as if it was never received. That means retransmits, if applicable, will keep going ๐Ÿ”

10.2. Long-Term Credential Mechanism ๐Ÿ—๏ธ

The long-term credential mechanism relies on a long-term credential, which is a username and password shared between the client and the server ๐Ÿซ‚. It's called long-term because it's assumed to be provisioned for a user and to stay in effect until that user stops being a subscriber of the system or the credential gets changed. Basically, it's the traditional "log-in" username and password people get handed ๐Ÿ’…

Because these usernames and passwords are expected to stay valid for long stretches of time, replay prevention comes in the form of a digest challenge ๐Ÿ›ก๏ธ Here's how it goes: the client first sends a request without offering any credentials or any integrity checks. The server rejects that request and gives the user a realm (used to guide the user or agent in picking a username and password) plus a nonce. The nonce is what provides the replay protection. It's a cookie chosen by the server and encoded in a way that indicates either a duration of validity or the client identity it's valid for โœจ. The client then retries the request, this time including its username and the realm, and echoing the nonce the server gave it. The client also includes a message-integrity, which is an HMAC over the entire request, nonce included ๐Ÿง. The server validates the nonce and checks the message integrity. If both match, the request is authenticated ๐ŸŽ‰. If the nonce is no longer valid, it's considered "stale," and the server rejects the request and hands back a new nonce ๐Ÿซ 

In later requests to the same server, the client reuses the nonce, username, realm, and password it used before ๐Ÿ”. That way, those requests don't get rejected until the server invalidates the nonce. At that point, the rejection comes with a new nonce for the client.

Note that the long-term credential mechanism cannot be used to protect indications, since indications cannot be challenged ๐Ÿšซ. Usages that use indications must either use a short-term credential or omit authentication and message integrity for them.

Since the long-term credential mechanism is susceptible to offline dictionary attacks, deployments SHOULD utilize passwords that are difficult to guess ๐Ÿ‘€. When the credentials aren't entered by a user, but are instead placed on a client device during device provisioning, the password SHOULD have at least 128 bits of randomness ๐ŸŽฒ. When the credentials are entered by the user, they should follow best current practices around password structure ๐Ÿ”‘

10.2.1. Forming a Request ๐Ÿ“

There are two cases when forming a request ๐Ÿ’. In the first case, it's the first request from the client to the server (identified by its IP address and port). In the second case, the client is submitting a subsequent request after a previous request/response transaction has completed successfully. Forming a request because of a 401 or 438 error response is covered in Section 10.2.3, and it's not considered a "subsequent request," so it doesn't use the rules described in Section 10.2.1.2 ๐Ÿ™…โ€โ™€๏ธ

10.2.1.1. First Request ๐ŸŒฑ

If the client hasn't completed a successful request/response transaction with the server (identified by hostname if the DNS procedures of Section 9 are used, or by IP address if not), it SHOULD omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes ๐Ÿซง. In other words, the very first request goes out as if no authentication or message integrity were applied.

10.2.1.2. Subsequent Requests ๐Ÿ”

Once a request/response transaction has completed successfully, the client has been given a realm and nonce by the server, and has picked a username and password to authenticate with ๐ŸŽ€. The client SHOULD cache the username, password, realm, and nonce for later communication with the server. When the client sends a subsequent request, it SHOULD include the USERNAME, REALM, and NONCE attributes with those cached values. It SHOULD also include a MESSAGE-INTEGRITY attribute, computed as described in Section 15.4 using the cached password ๐Ÿ’–

10.2.2. Receiving a Request ๐Ÿ›Ž๏ธ

After the server finishes the basic processing of a request, it runs the checks below in the order specified ๐Ÿ•ต๏ธโ€โ™€๏ธ

  • If the message does not contain a MESSAGE-INTEGRITY attribute, the server MUST generate an error response with an error code of 401 (Unauthorized). This response MUST include a REALM value. It is RECOMMENDED that the REALM value be the domain name of the provider of the STUN server ๐ŸŒ. The response MUST include a NONCE, selected by the server. The response SHOULD NOT contain a USERNAME or MESSAGE-INTEGRITY attribute.
  • If the message contains a MESSAGE-INTEGRITY attribute but is missing the USERNAME, REALM, or NONCE attribute, the server MUST generate an error response with an error code of 400 (Bad Request). This response SHOULD NOT include a USERNAME, NONCE, REALM, or MESSAGE-INTEGRITY attribute.
  • If the NONCE is no longer valid, the server MUST generate an error response with an error code of 438 (Stale Nonce). This response MUST include NONCE and REALM attributes and SHOULD NOT include the USERNAME or MESSAGE-INTEGRITY attribute. Servers can invalidate nonces to add some extra security ๐Ÿ›ก๏ธ See Section 4.3 of [RFC2617] for guidelines.
  • If the username in the USERNAME attribute isn't valid, the server MUST generate an error response with an error code of 401 (Unauthorized). This response MUST include a REALM value. It is RECOMMENDED that the REALM value be the domain name of the provider of the STUN server ๐ŸŒ. The response MUST include a NONCE, selected by the server. The response SHOULD NOT contain a USERNAME or MESSAGE-INTEGRITY attribute.
  • Using the password associated with the username in the USERNAME attribute, compute the value for the message integrity as described in Section 15.4. If the resulting value does not match the contents of the MESSAGE-INTEGRITY attribute, the server MUST reject the request with an error response. This response MUST use an error code of 401 (Unauthorized). It MUST include REALM and NONCE attributes and SHOULD NOT include the USERNAME or MESSAGE-INTEGRITY attribute.

If these checks pass, the server keeps processing the request โœ…. Any response the server generates (except in the cases described above) MUST include the MESSAGE-INTEGRITY attribute, computed using the username and password used to authenticate the request. The REALM, NONCE, and USERNAME attributes SHOULD NOT be included ๐Ÿ™ƒ

10.2.3. Receiving a Response ๐Ÿ“ฌ

If the response is an error response with an error code of 401 (Unauthorized), the client SHOULD retry the request with a new transaction ๐Ÿ”„. This request MUST contain a USERNAME, which the client determines as the appropriate username for the REALM from the error response. The request MUST contain the REALM, copied from the error response. The request MUST contain the NONCE, copied from the error response. The request MUST contain the MESSAGE-INTEGRITY attribute, computed using the password associated with the username in the USERNAME attribute. The client MUST NOT perform this retry if it isn't changing the USERNAME, REALM, or its associated password from the previous attempt ๐Ÿšซ

If the response is an error response with an error code of 438 (Stale Nonce), the client MUST retry the request using the new NONCE supplied in the 438 (Stale Nonce) response. This retry MUST also include the USERNAME, REALM, and MESSAGE-INTEGRITY ๐Ÿ’Œ

The client looks for the MESSAGE-INTEGRITY attribute in the response, whether it's a success or a failure. If it's present, the client computes the message integrity over the response as defined in Section 15.4, using the same password it used for the request. If the resulting value matches the contents of the MESSAGE-INTEGRITY attribute, the response is considered authenticated ๐Ÿ”. If the value doesn't match, or if MESSAGE-INTEGRITY was absent, the response MUST be discarded, as if it was never received. That means retransmits, if applicable, will continue ๐Ÿฆ‹

11. ALTERNATE-SERVER Mechanism ๐Ÿงš

okay so this section is all about how a server can redirect a client to a different server ๐Ÿฆ‹ This extension is optional, so a usage has to spell out if and when it gets used.

A server using this extension redirects a client by replying to a request with an error response that has the error code 300 (Try Alternate) ๐Ÿ’…. The server MUST include an ALTERNATE-SERVER attribute in that error response. The error response MAY be authenticated, but there are use cases for ALTERNATE-SERVER where authenticating the response isn't possible or practical ๐Ÿ™ˆ.

A client using this extension handles a 300 (Try Alternate) error code like this. It looks for an ALTERNATE-SERVER attribute in the error response. If it finds one, the client treats the current transaction as failed and retries the request with the server named in the attribute, using the same transport protocol as the previous request. That request, if authenticated, MUST utilize the same credentials the client would have used with the server that did the redirecting. If the client has already tried this request on a server it's been redirected to within the last five minutes, it MUST ignore the redirection and consider the transaction failed. This stops infinite ping-ponging between servers in case there's a redirection loop ๐Ÿ”


12. Backwards Compatibility with RFC 3489 ๐Ÿ•ฐ๏ธ

This section defines procedures that allow a degree of backwards compatibility with the original protocol, which is defined in RFC 3489 [RFC3489]. This mechanism is optional and is meant to be used only in cases where a new client can connect to an old server, or vice versa. A usage must define if and when this procedure is used.

Section 19 lists all the changes between this specification and RFC 3489 [RFC3489]. Not all of those differences matter, though, because "classic STUN" was only used in a few specific ways. For the purposes of this extension, the important changes are the following. In RFC 3489:

  • UDP was the only supported transport.
  • The field that is now the magic cookie field was a part of the transaction ID field, and transaction IDs were 128 bits long.
  • The XOR-MAPPED-ADDRESS attribute did not exist, and the Binding method used the MAPPED-ADDRESS attribute instead.
  • There were three comprehension-required attributes, RESPONSE-ADDRESS, CHANGE-REQUEST, and CHANGED-ADDRESS, that have been removed from this specification.
    • CHANGE-REQUEST and CHANGED-ADDRESS are now part of the NAT Behavior Discovery usage [BEHAVE-NAT], and the other is deprecated.

12.1. Changes to Client Processing ๐Ÿ’–

A client that wants to interoperate with an [RFC3489] server SHOULD send a request message that uses the Binding method, contains no attributes, and uses UDP as the transport protocol to the server. If it succeeds, the success response from the server will contain a MAPPED-ADDRESS attribute rather than an XOR-MAPPED-ADDRESS attribute. A client that's trying to interoperate with an older server MUST be prepared to receive either. Furthermore, the client MUST ignore any Reserved comprehension-required attributes that might appear in the response. Of the Reserved attributes in Section 18.2, 0x0002, 0x0004, 0x0005, and 0x000B may appear in Binding responses from a server compliant to RFC 3489. Other than this change, the processing of the response is identical to the procedures described above.

12.2. Changes to Server Processing โœจ

A STUN server can detect when a given Binding request message was sent from an RFC 3489 [RFC3489] client because the correct value is absent from the magic cookie field. When the server detects an RFC 3489 client, it SHOULD copy the value seen in the magic cookie field in the Binding request to the magic cookie field in the Binding response message, and insert a MAPPED-ADDRESS attribute instead of an XOR-MAPPED-ADDRESS attribute.

The client might, in rare situations, include either the RESPONSE-ADDRESS or CHANGE-REQUEST attributes. In those situations, the server will treat them as unknown comprehension-required attributes and reply with an error response. Since the mechanisms that use those attributes are no longer supported, this behavior is acceptable.

The RFC 3489 version of STUN lacks both the magic cookie and the FINGERPRINT attribute, which together allow for a very high probability of correctly identifying STUN messages when they're multiplexed with other protocols. Therefore, STUN implementations that are backwards compatible with RFC 3489 SHOULD NOT be used in cases where STUN will be multiplexed with another protocol. However, that shouldn't be an issue, since that kind of multiplexing wasn't available in RFC 3489.


13. Basic Server Behavior ๐ŸŒธ

This section defines the behavior of a basic, stand-alone STUN server. A basic STUN server gives clients their server reflexive transport addresses by receiving and replying to STUN Binding requests.

The STUN server MUST support the Binding method. It SHOULD NOT utilize the short-term or long-term credential mechanism, because the work involved in authenticating the request is more than the work of simply processing it. For the same reason, it SHOULD NOT utilize the ALTERNATE-SERVER mechanism. It MUST support UDP and TCP. It MAY support STUN over TCP/TLS; however, TLS provides minimal security benefits in this basic mode of operation. It MAY utilize the FINGERPRINT mechanism but MUST NOT require it. Since the stand-alone server only runs STUN, FINGERPRINT provides no benefit. Requiring it would break compatibility with RFC 3489, and that compatibility is desirable in a stand-alone server. Stand-alone STUN servers SHOULD support backwards compatibility with [RFC3489] clients, as described in Section 12.

It is RECOMMENDED that administrators of STUN servers provide DNS entries for those servers, as described in Section 9.

A basic STUN server isn't a solution for NAT traversal all on its own ๐Ÿฅบ However, it can be used as part of a solution through STUN usages. This is discussed further in Section 14.


14. STUN Usages ๐Ÿฆ‹

STUN by itself is not a solution to the NAT traversal problem. Instead, STUN defines a tool that can be used inside a larger solution. The term "STUN usage" refers to any solution that uses STUN as a component.

At the time of writing, three STUN usages are defined: Interactive Connectivity Establishment (ICE) [MMUSIC-ICE], Client-initiated connections for SIP [SIP-OUTBOUND], and NAT Behavior Discovery [BEHAVE-NAT]. Other STUN usages may be defined in the future.

A STUN usage defines how STUN is actually used: when to send requests, what to do with the responses, and which optional procedures defined here (or in an extension to STUN) are to be used. A usage would also define:

  • Which STUN methods are used.
  • What authentication and message-integrity mechanisms are used.
  • The considerations around manual vs. automatic key derivation for the integrity mechanism, as discussed in [RFC4107].
  • What mechanisms are used to distinguish STUN messages from other messages. When STUN is run over TCP, a framing mechanism may be required.
  • How a STUN client determines the IP address and port of the STUN server.
  • Whether backwards compatibility to RFC 3489 is required.
  • What optional attributes defined here (such as FINGERPRINT and ALTERNATE-SERVER) or in other extensions are required.

In addition, any STUN usage must consider the security implications of using STUN in that usage. A number of attacks against STUN are known (see the Security Considerations section in this document), and any usage must consider how these attacks can be thwarted or mitigated. ๐Ÿšจ

Finally, a usage must consider whether its use of STUN is an example of the Unilateral Self-Address Fixing approach to NAT traversal. If it is, the usage must address the questions raised in RFC 3424 [RFC3424]. ๐Ÿง


15. STUN Attributes ๐ŸŽ€

After the STUN header come zero or more attributes. Each attribute MUST be TLV encoded, with a 16-bit type, a 16-bit length, and a value. Each STUN attribute MUST end on a 32-bit boundary. As mentioned above, all fields in an attribute are transmitted most significant bit first. ๐Ÿ’œ

       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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |         Type                  |            Length             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         Value (variable)                ....
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 4: Format of STUN Attributes

The value in the length field MUST contain the length of the Value part of the attribute, before padding, measured in bytes. Since STUN aligns attributes on 32-bit boundaries, attributes whose content isn't a multiple of 4 bytes are padded with 1, 2, or 3 bytes so that the value contains a multiple of 4 bytes. The padding bits are ignored, and may be any value.

Any attribute type MAY appear more than once in a STUN message. Unless specified otherwise, the order of appearance is significant: only the first occurrence needs to be processed by a receiver, and any duplicates MAY be ignored by a receiver. ๐Ÿ”

To allow future revisions of this specification to add new attributes if needed, the attribute space is divided into two ranges. Attributes with type values between 0x0000 and 0x7FFF are comprehension-required attributes, which means that the STUN agent cannot successfully process the message unless it understands the attribute. Attributes with type values between 0x8000 and 0xFFFF are comprehension-optional attributes, which means that the STUN agent can ignore them if it doesn't understand them. โœจ

The set of STUN attribute types is maintained by IANA. The initial set defined by this specification is found in Section 18.2.

The rest of this section describes the format of the various attributes defined in this specification. ๐ŸŒˆ

15. STUN Attributes โœจ

15.1. MAPPED-ADDRESS ๐Ÿฆ‹

okay so MAPPED-ADDRESS tells the client its own reflexive transport address, aka the address the outside world sees for it ๐Ÿ‘€ It's made of an 8-bit address family, a 16-bit port, and then a fixed-length chunk for the IP address. For IPv4 the address MUST be 32 bits, and for IPv6 it MUST be 128 bits. Everything has to be in network byte order, no exceptions ๐Ÿซถ

    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|    Family     |           Port                |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   |                 Address (32 bits or 128 bits)                 |
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            Figure 5: Format of MAPPED-ADDRESS Attribute

The address family can be one of these values ๐Ÿ’œ

0x01:IPv4
0x02:IPv6

The first 8 bits of MAPPED-ADDRESS MUST be set to 0, and receivers MUST ignore them ๐Ÿ™ˆ They're just there so the parameters line up on natural 32-bit boundaries. Honestly the most aligned padding ever ๐ŸŒธ

This attribute is only used by servers for backwards compatibility with RFC 3489 [RFC3489] clients. Legacy vibes only ๐Ÿงš

15.2. XOR-MAPPED-ADDRESS ๐Ÿ”ฅ

XOR-MAPPED-ADDRESS is basically MAPPED-ADDRESS's glow-up, except the reflexive transport address gets scrambled with XOR so it's obfuscated ๐ŸŽ€

    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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |x x x x x x x x|    Family     |         X-Port                |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                X-Address (Variable)
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

           Figure 6: Format of XOR-MAPPED-ADDRESS Attribute

The Family means the IP address family and is encoded exactly like the Family in MAPPED-ADDRESS ๐Ÿ’…

Here's the math, bestie ๐Ÿงฎ For X-Port, you take the mapped port in host byte order, XOR it with the most significant 16 bits of the magic cookie, and then convert the result to network byte order. For IPv4, X-Address is the mapped IP address in host byte order XOR'd with the magic cookie, converted to network byte order. For IPv6, you XOR the mapped IP address in host byte order with the magic cookie concatenated with the 96-bit transaction ID, then convert to network byte order. Main character math ๐Ÿ‘‘

The rules for the first 8 bits, for handling multiple occurrences, and for address families are all the same as MAPPED-ADDRESS, so you don't have to relearn anything ๐ŸŒˆ

Note: XOR-MAPPED-ADDRESS and MAPPED-ADDRESS only differ in how they encode the transport address. XOR-MAPPED-ADDRESS XORs it with the magic cookie, and MAPPED-ADDRESS just stores it as plain binary. RFC 3489 originally specified only MAPPED-ADDRESS [RFC3489]. But then deployment experience showed that some NATs rewrite 32-bit binary payloads containing the NAT's public IP address, like the MAPPED-ADDRESS attribute in STUN, trying to be helpful with a generic ALG function. Bestie, that is NOT the vibe ๐Ÿ’€ It messes up STUN and also breaks STUN's message-integrity checking.

15.3. USERNAME ๐Ÿ“

USERNAME is used for message integrity. It tells you which username and password combo went into the message-integrity check ๐Ÿ”

The value is variable-length. It MUST contain a UTF-8 [RFC3629] encoded sequence of fewer than 513 bytes, and it MUST have been processed using SASLprep [RFC4013] first. Gotta get that prep done before you show up ๐Ÿ’–

15.4. MESSAGE-INTEGRITY ๐Ÿ’œ

MESSAGE-INTEGRITY holds an HMAC-SHA1 [RFC2104] of the STUN message. It can show up in any STUN message type. Because it's SHA1, the HMAC is 20 bytes โœจ The HMAC input is the STUN message, header included, up to and including the attribute right before MESSAGE-INTEGRITY. The only thing allowed to come after it is FINGERPRINT, which is the exception. Other than that, agents MUST ignore all the other attributes that follow MESSAGE-INTEGRITY ๐Ÿ™…โ€โ™€๏ธ

The key depends on whether you're using long-term or short-term credentials ๐Ÿ—๏ธ For long-term credentials the key is 16 bytes:

key = MD5(username ":" realm ":" SASLprep(password))

So basically, the 16-byte key is the MD5 hash of five fields glued together, in order: (1) the username, with any quotes and trailing nulls removed, taken from the USERNAME attribute (SASLprep already applied); (2) a single colon; (3) the realm, with any quotes and trailing nulls removed; (4) another single colon; and (5) the password, with trailing nulls removed and SASLprep applied. Example time ๐ŸŽ€ If the username was 'user', the realm was 'realm', and the password was 'pass', the 16-byte HMAC key is the MD5 hash of the string 'user:realm:pass', which comes out to 0x8493fbc53ba582fb4c044c456bdc40eb ๐Ÿฆ‹

For short-term credentials it's way simpler:

key = SASLprep(password)

Quick recap: MD5 is defined in RFC 1321 [RFC1321] and SASLprep() is defined in RFC 4013 [RFC4013].

Fun fact that's lowkey iconic: the long-term key structure is built so it works with systems that also use SIP ๐ŸŒธ SIP systems using SIP's digest authentication usually don't store the actual password. They store something called H(A1), which is equal to the key above ๐Ÿงš

Now the tricky part ๐Ÿ™ˆ The hash used to build MESSAGE-INTEGRITY includes the length field from the STUN message header. So before hashing, the MESSAGE-INTEGRITY attribute MUST be inserted into the message with dummy content. Then the length MUST then be set to point to the message length up to and including the MESSAGE-INTEGRITY attribute itself, but not any attributes after it. Once the computation is done, you fill in the real MESSAGE-INTEGRITY value and set the STUN header length to its correct value, which is the length of the whole message. When validating, the length field should be adjusted to point to the end of MESSAGE-INTEGRITY before you calculate the HMAC. That adjustment is needed when stuff like FINGERPRINT shows up after MESSAGE-INTEGRITY ๐Ÿ˜ญ

15.5. FINGERPRINT ๐ŸŒˆ

FINGERPRINT MAY be present in all STUN messages ๐Ÿ’… Its value is the CRC-32 of the STUN message up to, but not including, the FINGERPRINT attribute itself, and then it gets XOR'd with the 32-bit value 0x5354554e. The XOR is there because some applications already use CRC-32 in their own packets, so this keeps things from getting mixed up โœจ The 32-bit CRC is the one from ITU V.42 [ITU.V42.2002], with the generator polynomial x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1. ๐Ÿงฎ

When it's present, FINGERPRINT MUST be the last attribute in the message, so it ends up after MESSAGE-INTEGRITY ๐Ÿซถ

The FINGERPRINT attribute can help tell STUN packets apart from packets of other protocols. See Section 8. ๐Ÿฆ‹

Just like MESSAGE-INTEGRITY, the CRC covers the length field from the STUN message header. So that length has to be correct and already include the CRC attribute as part of the message length before you compute the CRC. ๐Ÿ™ˆ The process goes like this: put the attribute in with a dummy value, compute the CRC, then update the attribute's value. And if MESSAGE-INTEGRITY is also present, it must already have the correct message-integrity value before the CRC is computed, because the CRC covers MESSAGE-INTEGRITY too ๐Ÿ‘‘

15.6. ERROR-CODE ๐Ÿšจ

okay so the ERROR-CODE attribute is the one that shows up in error response messages ๐Ÿ’€ it carries a numeric error code in the range of 300 to 699, plus a reason phrase encoded in UTF-8 [RFC3629]. the codes match up with SIP [RFC3261] and HTTP [RFC2616], so anyone who already knows those is literally set ๐Ÿซถ the reason phrase is for humans to read, so it can say whatever fits the code. the recommended phrases live in the IANA registry for error codes ๐Ÿ“‹ the reason phrase MUST be a UTF-8 [RFC3629] encoded sequence of less than 128 characters (which can be as long as 763 bytes) ๐ŸŽ€

    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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Reserved, should be 0         |Class|     Number    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Reason Phrase (variable)                                ..
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                   Figure 7: ERROR-CODE Attribute

to make processing easier, the class of the error code (the hundreds digit) is encoded separately from the rest of the code, as shown in Figure 7 ๐Ÿงš

the Reserved bits SHOULD be 0, and they're there for alignment on 32-bit boundaries. receivers MUST ignore these bits ๐Ÿ™ˆ the Class represents the hundreds digit of the error code, and its value MUST be between 3 and 6. the Number represents the error code modulo 100, and its value MUST be between 0 and 99 โœจ

these error codes, along with their recommended reason phrases, are defined:

  • 300 Try Alternate: the client should contact an alternate server for this request. this error response MUST only be sent if the request included a USERNAME attribute and a valid MESSAGE-INTEGRITY attribute. otherwise, it MUST NOT be sent, and error code 400 (Bad Request) is suggested. this error response MUST be protected with the MESSAGE-INTEGRITY attribute, and receivers MUST validate the MESSAGE-INTEGRITY of this response before redirecting themselves to an alternate server ๐Ÿ”ฅ
Note: Failure to generate and validate message integrity for a 300 response allows an on-path attacker to falsify a 300 response, thus causing subsequent STUN messages to be sent to a victim. ๐Ÿ˜ญ
  • 400 Bad Request: the request was malformed. the client SHOULD NOT retry the request without modification from the previous attempt. the server may not be able to generate a valid MESSAGE-INTEGRITY for this error, so the client MUST NOT expect a valid MESSAGE-INTEGRITY attribute on this response ๐Ÿ™ƒ
  • 401 Unauthorized: the request did not contain the correct credentials to proceed. the client should retry the request with proper credentials ๐Ÿ”‘
  • 420 Unknown Attribute: the server received a STUN packet containing a comprehension-required attribute that it did not understand. the server MUST put this unknown attribute in the UNKNOWN-ATTRIBUTE attribute of its error response ๐Ÿ‘‘
  • 438 Stale Nonce: the NONCE used by the client was no longer valid. the client should retry, using the NONCE provided in the response ๐Ÿ’…
  • 500 Server Error: the server has suffered a temporary error. the client should try again ๐ŸŒธ

15.7. REALM ๐Ÿฐ

the REALM attribute may be present in requests and responses ๐Ÿฆ‹ it contains text that meets the grammar for "realm-value" as described in RFC 3261 [RFC3261], but without the double quotes and their surrounding whitespace. so it's an unquoted realm-value, which means it's a sequence of qdtext or quoted-pair ๐Ÿง  it MUST be a UTF-8 [RFC3629] encoded sequence of less than 128 characters (which can be as long as 763 bytes), and it MUST have been processed using SASLprep [RFC4013] ๐Ÿ’–

presence of the REALM attribute in a request indicates that long-term credentials are being used for authentication. presence in certain error responses indicates that the server wants the client to use a long-term credential for authentication ๐Ÿ”


15.8. NONCE ๐ŸŽฒ

the NONCE attribute may be present in requests and responses ๐Ÿ“ it contains a sequence of qdtext or quoted-pair, which are defined in RFC 3261 [RFC3261]. note that this means the NONCE attribute will not contain actual quote characters ๐Ÿ™Š see RFC 2617 [RFC2617], Section 4.3, for guidance on selecting nonce values in a server.

it MUST be less than 128 characters (which can be as long as 763 bytes) โœจ


15.9. UNKNOWN-ATTRIBUTES ๐Ÿ”

the UNKNOWN-ATTRIBUTES attribute is present only in an error response when the response code in the ERROR-CODE attribute is 420 ๐Ÿซฃ

the attribute contains a list of 16-bit values, and each one represents an attribute type that the server didn't understand ๐Ÿ’œ

    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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Attribute 1 Type           |     Attribute 2 Type        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Attribute 3 Type           |     Attribute 4 Type    ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


          Figure 8: Format of UNKNOWN-ATTRIBUTES Attribute
Note: In [RFC3489], this field was padded to 32 by duplicating the last attribute. In this version of the specification, the normal padding rules for attributes are used instead. ๐Ÿงต

15.10. SOFTWARE ๐Ÿ’ป

the SOFTWARE attribute contains a textual description of the software being used by the agent sending the message ๐Ÿ› ๏ธ it's used by clients and servers. its value SHOULD include the manufacturer and version number. the attribute has no impact on how the protocol operates, and it only serves as a tool for diagnostic and debugging purposes ๐Ÿ”ง the value of SOFTWARE is variable length. it MUST be a UTF-8 [RFC3629] encoded sequence of less than 128 characters (which can be as long as 763 bytes) ๐ŸŒˆ


15.11. ALTERNATE-SERVER ๐Ÿ”€

the alternate server represents an alternate transport address identifying a different STUN server that the STUN client should try ๐Ÿงšโ€โ™€๏ธ

it's encoded in the same way as MAPPED-ADDRESS, so it refers to a single server by IP address. the IP address family MUST be identical to that of the source IP address of the request ๐ŸŒธ


16. Security Considerations ๐Ÿ”๐Ÿ˜ค

this part is serious, bestie, so let's be dramatic about it ๐ŸŽญ

16.1. Attacks against the Protocol ๐Ÿ—ก๏ธ

16.1.1. Outside Attacks ๐Ÿ•ต๏ธโ€โ™€๏ธ

an attacker can try to modify STUN messages in transit, to cause a failure in STUN operation ๐Ÿ˜ˆ these attacks are detected for both requests and responses through the message-integrity mechanism, using either a short-term or long-term credential. of course, once detected, the manipulated packets will be dropped, so the STUN transaction effectively fails ๐Ÿ’€ this attack is possible only by an on-path attacker.

an attacker that can observe, but not modify, STUN messages in transit (for example, an attacker present on a shared access medium, such as Wi-Fi) can see a STUN request and then immediately send a STUN response, typically an error response, to disrupt STUN processing ๐Ÿ‘€ this attack is also prevented for messages that use MESSAGE-INTEGRITY. however, some error responses, especially those related to authentication, cannot be protected by MESSAGE-INTEGRITY. when STUN itself is run over a secure transport protocol (e.g., TLS), these attacks are completely mitigated ๐Ÿ”’

depending on the STUN usage, these attacks may be of minimal consequence and thus do not require message integrity to mitigate ๐Ÿคทโ€โ™€๏ธ for example, when STUN is used with a basic STUN server to discover a server reflexive candidate for use with ICE, authentication and message integrity are not required, since these attacks are detected during the connectivity check phase. the connectivity checks themselves, however, require protection for ICE to operate properly overall ๐Ÿงฉ as described in Section 14, STUN usages describe when authentication and message integrity are needed ๐Ÿ“–

since STUN uses the HMAC of a shared secret for authentication and integrity protection, it is subject to offline dictionary attacks ๐Ÿ˜ฐ when authentication is used, it SHOULD be with a strong password that is not readily subject to offline dictionary attacks. protection of the channel itself, using TLS, mitigates these attacks. however, STUN is most often run over UDP, and in those cases, strong passwords are the only way to protect against these attacks ๐Ÿ’ช

16.1.2. Inside Attacks ๐Ÿ˜ˆ

a rogue client may try to launch a DoS attack against a server by sending it a large number of STUN requests. luckily, STUN requests can be processed statelessly by a server, which makes such attacks hard to launch ๐Ÿ™Œ

a rogue client may use a STUN server as a reflector, sending it requests with a falsified source IP address and port. in such a case, the response would be delivered to that source IP and port ๐Ÿ“ฌ there is no amplification of the number of packets with this attack (the STUN server sends one packet for each packet sent by the client), though there is a small increase in the amount of data, since STUN responses are typically larger than requests. this attack is mitigated by ingress source address filtering ๐Ÿšง

revealing the specific software version of the agent through the SOFTWARE attribute might make it easier for them to become more vulnerable to attacks against software that is known to contain security holes ๐Ÿ˜ฑ implementers SHOULD make usage of the SOFTWARE attribute a configurable option โš™๏ธ

16.2. Attacks Affecting the Usage ๐ŸŽฏ

this section lists attacks that might be launched against a usage of STUN. each STUN usage must consider whether these attacks are applicable to it, and if so, discuss counter-measures ๐Ÿ“

most of the attacks in this section revolve around an attacker modifying the reflexive address learned by a STUN client through a Binding request/response transaction ๐Ÿชž since the usage of the reflexive address depends on the usage, the applicability and remediation of these attacks are usage-specific. in common situations, modifying the reflexive address by an on-path attacker is easy to do. consider, for example, the common situation where STUN is run directly over UDP. in this case, an on-path attacker can modify the source IP address of the Binding request before it arrives at the STUN server ๐Ÿ˜ฌ the STUN server will then return this IP address in the XOR-MAPPED-ADDRESS attribute to the client, and send the response back to that (falsified) IP address and port. if the attacker can also intercept this response, it can direct it back towards the client ๐Ÿ™€ protecting against this attack by using a message-integrity check is impossible, since a message-integrity value cannot cover the source IP address, because the intervening NAT must be able to modify this value ๐Ÿงฑ instead, one solution to preventing the attacks listed below is for the client to verify the reflexive address learned, as is done in ICE [MMUSIC-ICE]. other usages may use other means to prevent these attacks ๐ŸŒŸ

16.2.1. Attack I: Distributed DoS (DDoS) against a Target

okay so in this attack, the attacker hands one or more clients the same faked reflexive address, and that address points at the intended target ๐Ÿ’€. This tricks the STUN clients into thinking their reflexive addresses are equal to the target's ๐Ÿ™ˆ. If the clients hand that reflexive address out to receive traffic on it (like in SIP messages, for example), the traffic gets sent to the target instead ๐ŸŽฏ. This attack can provide substantial amplification, especially with clients using STUN for multimedia apps ๐Ÿ“ž. Lowkey the catch is that it can only be launched against targets where packets from the STUN server to the target pass through the attacker ๐Ÿ™…โ€โ™€๏ธ, so it's not possible in every case.

16.2.2. Attack II: Silencing a Client

bestie, in this attack the attacker gives a STUN client a faked reflexive address ๐Ÿซ . The address it provides is a transport address that routes to nowhere ๐Ÿ•ณ๏ธ. So the client won't receive any of the packets it expects when it hands out that reflexive address. ngl this one isn't very interesting for the attacker ๐Ÿฅฑ, since it only impacts a single client, which is frequently not the desired target. Also, any attacker who can pull this off could deny service to the client in other ways, like stopping the client from getting any response from the STUN server, or even from a DHCP server ๐Ÿ™„. Just like with the attack in Section 16.2.1, this one is only possible when the attacker is on path for packets sent from the STUN server towards this unused IP address ๐Ÿ›ค๏ธ.

16.2.3. Attack III: Assuming the Identity of a Client

this one is giving "similar to attack II" energy ๐Ÿ’…, but with a twist. The faked reflexive address points to the attacker itself ๐Ÿ˜ˆ. That means the attacker gets to receive traffic that was destined for the client ๐Ÿ“ฌ. Iconic villain move, honestly.

16.2.4. Attack IV: Eavesdropping

okay so here the attacker forces the client to use a reflexive address that routes to itself ๐Ÿ•ต๏ธโ€โ™€๏ธ. Then it forwards any packets it receives on to the client. This would let the attacker observe all packets sent to the client ๐Ÿ‘€. BUT, and this is a big but, in order to launch the attack the attacker must have already been able to observe packets from the client to the STUN server ๐Ÿ™ƒ. In most cases (like when the attack is launched from an access network), this means the attacker could already observe packets sent to the client anyway ๐Ÿคทโ€โ™€๏ธ. So this attack is only really useful for observing traffic by attackers on the path from the client to the STUN server, and not generally on the path of packets being routed towards the client ๐Ÿงš.

16.3. Hash Agility Plan

so this specification uses HMAC-SHA-1 for computing the message integrity ๐Ÿ”. If, at a later time, HMAC-SHA-1 is found to be compromised, here's the remedy that will be applied ๐Ÿ› ๏ธ.

We will define a STUN extension that introduces a new message-integrity attribute, computed using a new hash โœจ. Clients would be required to include both the new and old message-integrity attributes in their requests or indications ๐Ÿ“. A new server will use the new message-integrity attribute, and an old one will use the old ๐Ÿซถ. After a transition period where mixed implementations are in deployment, the old message-integrity attribute will be deprecated by another specification, and clients will cease including it in requests ๐Ÿ‘‹.

It's also important to note that the HMAC is done using a key that is itself computed using an MD5 of the user's password ๐Ÿง. The choice of the MD5 hash was made because of the existence of legacy databases that store passwords in that form ๐Ÿ—„๏ธ. If future work finds that an HMAC of an MD5 input is not secure, and a different hash is needed, it can also be changed using this plan ๐Ÿ”„. However, this would require administrators to repopulate their databases ๐Ÿ˜ญ.

17. 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 other side of a NAT, using a collaborative protocol reflection mechanism (RFC3424 [RFC3424]) ๐Ÿ”. STUN can do this job using a Binding request/response transaction if one agent is behind a NAT and the other is on the public side of the NAT ๐ŸŒ.

The IAB has mandated that protocols developed for this purpose document a specific set of considerations ๐Ÿ“‹. Some STUN usages provide UNSAF functions (like ICE [MMUSIC-ICE]), and others don't (like SIP Outbound [SIP-OUTBOUND]) ๐Ÿ™…โ€โ™€๏ธ. So the answers to these considerations need to be addressed by the usages themselves ๐Ÿ’–.

18. IANA Considerations

okay IANA has created three new registries ๐Ÿ“š: a "STUN Methods Registry", a "STUN Attributes Registry", and a "STUN Error Codes Registry" ๐ŸŽ€. IANA has also changed the name of the assigned IANA port for STUN from "nat-stun-port" to "stun" ๐Ÿ”.

18.1. STUN Methods Registry

a STUN method is a hex number in the range 0x000 - 0xFFF ๐Ÿ”ข. The encoding of a STUN method into a STUN message is described in Section 6 ๐Ÿงฉ.

the initial STUN methods are:

0x000: (Reserved)
0x001: Binding
0x002: (Reserved; was SharedSecret)

STUN methods in the range 0x000 - 0x7FF are assigned by IETF Review [RFC5226] ๐Ÿ›๏ธ. STUN methods in the range 0x800 - 0xFFF are assigned by Designated Expert [RFC5226] ๐Ÿ‘ฉโ€๐Ÿ’ผ. The expert's job is to verify that the selected codepoint(s) are not in use and that the request isn't for an abnormally large number of codepoints ๐Ÿ”Ž. Technical review of the extension itself is outside the scope of the designated expert responsibility ๐Ÿ™Œ.

18.2. STUN Attribute Registry

a STUN Attribute type is a hex number in the range 0x0000 - 0xFFFF ๐Ÿ’ซ. STUN attribute types in the range 0x0000 - 0x7FFF are considered comprehension-required, and STUN attribute types in the range 0x8000 - 0xFFFF are considered comprehension-optional ๐Ÿง . A STUN agent handles unknown comprehension-required and comprehension-optional attributes differently ๐Ÿค”.

the initial STUN Attributes types are:

Comprehension-required range (0x0000-0x7FFF):
  0x0000: (Reserved)
  0x0001: MAPPED-ADDRESS
  0x0002: (Reserved; was RESPONSE-ADDRESS)
  0x0003: (Reserved; was CHANGE-ADDRESS)
  0x0004: (Reserved; was SOURCE-ADDRESS)
  0x0005: (Reserved; was CHANGED-ADDRESS)
  0x0006: USERNAME
  0x0007: (Reserved; was PASSWORD)
  0x0008: MESSAGE-INTEGRITY
  0x0009: ERROR-CODE
  0x000A: UNKNOWN-ATTRIBUTES
  0x000B: (Reserved; was REFLECTED-FROM)
  0x0014: REALM
  0x0015: NONCE
  0x0020: XOR-MAPPED-ADDRESS

Comprehension-optional range (0x8000-0xFFFF)
  0x8022: SOFTWARE
  0x8023: ALTERNATE-SERVER
  0x8028: FINGERPRINT

STUN Attribute types in the first half of the comprehension-required range (0x0000 - 0x3FFF) and in the first half of the comprehension-optional range (0x8000 - 0xBFFF) are assigned by IETF Review [RFC5226] ๐Ÿ—‚๏ธ. STUN Attribute types in the second half of the comprehension-required range (0x4000 - 0x7FFF) and in the second half of the comprehension-optional range (0xC000 - 0xFFFF) are assigned by Designated Expert [RFC5226] ๐Ÿง‘โ€๐Ÿ’ป. The expert's job is to verify that the selected codepoint(s) are not in use, and that the request isn't for an abnormally large number of codepoints ๐Ÿ’…. Technical review of the extension itself is outside the scope of the designated expert responsibility ๐Ÿซถ.

18.3. STUN Error Code Registry

a STUN error code is a number in the range 0 - 699 ๐Ÿšจ. STUN error codes come with a textual reason phrase in UTF-8 [RFC3629] that is intended only for human consumption and can be anything appropriate ๐Ÿ—ฃ๏ธ. This document only proposes suggested values, though ๐Ÿ’ญ.

STUN error codes are consistent in codepoint assignments and semantics with SIP [RFC3261] and HTTP [RFC2616] ๐Ÿค.

The initial values in this registry are given in Section 15.6 ๐Ÿ“.

New STUN error codes are assigned based on IETF Review [RFC5226]. The specification must carefully consider how clients that do not understand this error code will process it before granting the request ๐Ÿง. See the rules in Section 7.3.4 ๐Ÿ“–.

18.4. STUN UDP and TCP Port Numbers

okay so IANA previously assigned port 3478 for STUN ๐ŸŽˆ. This port shows up in the IANA registry under the moniker "nat-stun-port" ๐Ÿท๏ธ. To line up the DNS SRV procedures with the registered protocol service, IANA is asked to change the name of the protocol assigned to port 3478 from "nat-stun-port" to "stun" ๐Ÿ”„. The textual name also changes, from "Simple Traversal of UDP Through NAT (STUN)" to "Session Traversal Utilities for NAT" โœจ. So the IANA port registry would read:

stun   3478/tcp   Session Traversal Utilities for NAT (STUN) port
stun   3478/udp   Session Traversal Utilities for NAT (STUN) port

In addition, IANA has assigned port number 5349 for the "stuns" service, defined over TCP and UDP ๐Ÿ”. The UDP port isn't currently defined, but it's reserved for future use ๐ŸŒธ.

19. Changes since RFC 3489 โœจ

This spec obsoletes [RFC3489] ๐Ÿซถ Here's everything that's different from RFC 3489, bestie:

  • Dropped the idea that STUN is a complete NAT traversal solution ๐Ÿ™…โ€โ™€๏ธ STUN is now a tool you can use to build a NAT traversal solution ๐Ÿ”ง That's why the protocol got renamed to Session Traversal Utilities for NAT.
  • Introduced the concept of STUN usages ๐Ÿ“ and spelled out what a usage of STUN has to document.
  • Removed using STUN for NAT type detection and binding lifetime discovery ๐Ÿ’€ These techniques proved overly brittle because NAT devices vary way more than this document described. Also removed the RESPONSE-ADDRESS, CHANGED-ADDRESS, CHANGE-REQUEST, SOURCE-ADDRESS, and REFLECTED-FROM attributes.
  • Added a fixed 32-bit magic cookie and shrank the transaction ID by 32 bits ๐Ÿ“ The magic cookie starts at the same offset the original transaction ID did.
  • Added the XOR-MAPPED-ADDRESS attribute ๐Ÿ” It's included in Binding responses if the magic cookie is present in the request. Otherwise, the RFC 3489 behavior is kept, so the Binding response includes MAPPED-ADDRESS. See the discussion in XOR-MAPPED-ADDRESS about this change.
  • Gave the message type header field formal structure ๐Ÿงฉ There's now an explicit pair of bits for request, response, error response, or indication. So the message type field is split into the class (one of those previous four) and the method.
  • Called out that the most significant 2 bits of STUN are 0b00 ๐ŸŒˆ This makes it super easy to tell STUN apart from RTP packets when used with ICE.
  • Added the FINGERPRINT attribute ๐Ÿฆ‹ It gives you a way to definitely detect the difference between STUN and another protocol when the two are multiplexed together.
  • Added IPv6 support ๐ŸŒธ Made it clear that an IPv4 client could get a v6 mapped address, and vice versa.
  • Added long-term-credential-based authentication ๐Ÿ”‘
  • Added the SOFTWARE, REALM, NONCE, and ALTERNATE-SERVER attributes โœจ
  • Removed the SharedSecret method, and thus the PASSWORD attribute ๐Ÿ‘‹ It was almost never implemented and isn't needed with current usages.
  • Removed the recommendation to keep listening for STUN responses for 10 seconds to try to recognize an attack ๐Ÿ™ˆ
  • Changed transaction timers to be more TCP friendly ๐Ÿ’œ
  • Removed the STUN example about separating the control and media planes ๐Ÿงš Instead, there's more info on using STUN with protocols.
  • Defined a generic padding mechanism that changes how the length attribute is interpreted. In theory this would break backwards compatibility ๐Ÿ˜ฌ But the RFC 3489 mechanism never worked for the few attributes that weren't naturally aligned on 32-bit boundaries, so no real loss.
  • REALM, SERVER, reason phrases, and NONCE are now limited to 127 characters. USERNAME is limited to 513 bytes.
  • Changed the DNS SRV procedures for TCP and TLS ๐ŸŽ€ UDP stays the same as before.

20. Contributors ๐ŸŒŸ

Christian Huitema and Joel Weinberger were the original co-authors of RFC 3489 ๐Ÿ‘‘

21. Acknowledgements ๐Ÿซถ

The authors would like to thank Cedric Aoun, Pete Cordell, Cullen Jennings, Bob Penfield, Xavier Marjou, Magnus Westerlund, Miguel Garcia, Bruce Lowekamp, and Chris Sullivan for their comments, and Baruch Sterman and Alan Hawrylyshen for their initial implementations. Thanks also to Leslie Daigle, Allison Mankin, Eric Rescorla, and Henning Schulzrinne for their IESG and IAB input on this work ๐Ÿ’–

22. References ๐Ÿ“š

22.1. Normative References

  • [ITU.V42.2002] International Telecommunications Union, "Error-correcting Procedures for DCEs Using Asynchronous-to-Synchronous Conversion", ITU-T Recommendation V.42, March 2002.
  • [RFC0791] Postel, J., "Internet Protocol", STD 5, RFC 791, September 1981.
  • [RFC1122] Braden, R., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, October 1989.
  • [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.
  • [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998.
  • [RFC2617] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999.
  • [RFC2782] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000.
  • [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
  • [RFC2988] Paxson, V. and M. Allman, "Computing TCP's Retransmission Timer", RFC 2988, November 2000.
  • [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.
  • [RFC4013] Zeilenga, K., "SASLprep: Stringprep Profile for User Names and Passwords", RFC 4013, February 2005.

22.2. Informative References

  • [BEHAVE-NAT] MacDonald, D. and B. Lowekamp, "NAT Behavior Discovery Using STUN", Work in Progress, July 2008.
  • [BEHAVE-TURN] Rosenberg, J., Mahy, R., and P. Matthews, "Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)", Work in Progress, July 2008.
  • [KARN87] Karn, P. and C. Partridge, "Improving Round-Trip Time Estimates in Reliable Transport Protocols", SIGCOMM 1987, August 1987.
  • [MMUSIC-ICE] Rosenberg, J., "Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols", Work in Progress, October 2007.
  • [MMUSIC-ICE-TCP] Rosenberg, J., "TCP Candidates with Interactive Connectivity Establishment (ICE)", Work in Progress, July 2008.
  • [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
  • [RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, June 2002.
  • [RFC3264] Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model with Session Description Protocol (SDP)", RFC 3264, June 2002.
  • [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.
  • [RFC4107] Bellovin, S. and R. Housley, "Guidelines for Cryptographic Key Management", BCP 107, RFC 4107, June 2005.
  • [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008.
  • [SIP-OUTBOUND] Jennings, C. and R. Mahy, "Managing Client Initiated Connections in the Session Initiation Protocol (SIP)", Work in Progress, June 2008.

Appendix A. C Snippet to Determine STUN Message Types ๐Ÿง‘โ€๐Ÿ’ป

Say you've got a 16-bit STUN message type value in host byte order, stored in the msg_type parameter. Here are C macros to figure out which STUN message type it is ๐Ÿ’…

#define IS_REQUEST(msg_type)       (((msg_type) & 0x0110) == 0x0000)
#define IS_INDICATION(msg_type)    (((msg_type) & 0x0110) == 0x0010)
#define IS_SUCCESS_RESP(msg_type)  (((msg_type) & 0x0110) == 0x0100)
#define IS_ERR_RESP(msg_type)      (((msg_type) & 0x0110) == 0x0110)

Authors' Addresses ๐Ÿฆ‹

Jonathan Rosenberg
Cisco
Edison, NJ
US

EMail: jdrosen@cisco.com
URI:   http://www.jdrosen.net


Rohan Mahy
Unaffiliated

EMail: rohan@ekabal.com


Philip Matthews
Unaffiliated

EMail: philip_matthews@magma.ca


Dan Wing
Cisco
771 Alder Drive
San Jose, CA  95035
US

EMail: dwing@cisco.com

Copyright (C) The IETF Trust (2008).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property ๐Ÿ”

The IETF takes no position on the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or on the extent to which any license under such rights might or might not be available. It also doesn't claim to have made any independent effort to identify any such rights. Info on the procedures for rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the result of an attempt to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be found in the IETF online IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology required to implement this standard. Please send that info to the IETF at ietf-ipr@ietf.org ๐Ÿซถ

๐Ÿ“ฆ where this page comes from