RFC 5456

IAX: Inter-Asterisk eXchange Version 2

📅 published February 2010, from ietf

RFC 5456: IAX: Inter-Asterisk eXchange Version 2 ✨

Okay bestie, let's start at the front page 🎀 This is RFC 5456, titled IAX: Inter-Asterisk eXchange Version 2. It came in as an Independent Submission, so it isn't an IETF stream document, and its category is Informational 🧚. It's dated February 2010 📅, and the ISSN is 2070-1721.

The authors are M. Spencer (Digium, Inc.), B. Capouch (Saint Joseph's College), E. Guy, Ed. (Truphone), F. Miller (Cornfed Systems, LLC), and K. Shumard 👑. The header doesn't list anything it obsoletes or updates, so it's a standalone doc 🦋.

Abstract

Okay so the abstract is basically the elevator pitch 💅 IAX is the Inter-Asterisk eXchange protocol. It's an application-layer control and media protocol for setting up, changing, and ending multimedia sessions over IP networks 🌸. The open source community made it for the Asterisk PBX, and it's mainly aimed at VoIP call control, but it can also carry streaming video or any other kind of multimedia ✨.

IAX is an "all in one" protocol 🍓 It handles control and media in the same protocol, which is iconic. It runs everything over a single UDP data stream on a static port, and that's a huge deal because it makes NAT traversal way easier 🙈 Other protocols don't need to do workarounds, and network and firewall management gets simpler too 🫶. IAX uses a compact encoding, so it eats less bandwidth and is a great fit for Internet telephony 💜. Its open design also lets new payload types get added whenever more services need them 🌈.

Status of This Memo

This part is the legal-ish stuff, but still easy 🦋

This document is not an Internet Standards Track spec. It's published for informational purposes 📚.

It's a contribution to the RFC Series, made independently of any other RFC stream. The RFC Editor chose to publish it at their discretion, and they make no statement about whether it's valuable for implementation or deployment 💅. Documents the RFC Editor approves for publication are not a candidate for any level of Internet Standard. See Section 2 of RFC 5741 for that 🧚.

For info on the current status, any errata, and how to send feedback, check http://www.rfc-editor.org/info/rfc5456 🔥.

IESG Note

This one is a big deal, so read carefully 🙈

This RFC is not a candidate for any level of Internet Standard. The IETF disclaims any knowledge of how fit it is for any purpose. It specifically says the decision to publish wasn't based on IETF review for things like security, congestion control, or inappropriate interaction with deployed protocols 💀. The RFC Editor chose to publish it at their discretion, so readers should be careful about judging its value for implementation and deployment ⚠️. See RFC 3932 for more info 🌸.

Read that again: the IETF didn't review this for security, congestion control, or how it plays with deployed protocols. Proceed with care, bestie 🫶

The IESG thinks this work is related to IETF work done in the SIP, MMUSIC, and AVT WGs, but that doesn't stop it from being published ✨.

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved 📝.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info), as they stood on the publication date. Please review those carefully, because they spell out your rights and restrictions for this document 🎀.

Table of Contents

Here's the full map so you can find your way around 🗺️

   1. Introduction ....................................................4
      1.1. Basic Properties ...........................................4
      1.2. Drawbacks ..................................................5
   2. IAX Terminology .................................................6
   3. Overview of IAX Protocol ........................................6
   4. Naming Conventions ..............................................8
   5. IAX Uniform Resource Identifiers ................................8
      5.1. IAX URI Scheme Registration ................................8
      5.2. URI Comparison ............................................11
   6. Peer Behavior and Related Messages .............................11
      6.1. Registration (OPTIONAL) ...................................12
      6.2. Call Leg Management .......................................18
      6.3. Call Control ..............................................24
      6.4. Mid-Call Link Operations ..................................26
      6.5. Call Path Optimization ....................................28
      6.6. Call Tear Down ............................................33
      6.7. Network Monitoring ........................................33
      6.8. Digit Dialing .............................................34
      6.9. Miscellaneous .............................................36
      6.10. Media Messages ...........................................38
   7. Message Transport ..............................................39
      7.1. Trunking ..................................................40
      7.2. Timers ....................................................41
      7.3. NAT Considerations ........................................41
      7.4. Encryption ................................................42
   8. Message Encoding ...............................................42
      8.1. Frame Structure ...........................................42
      8.2. Frame Types ...............................................52
      8.3. Control Frames Subclasses .................................55
      8.4. IAX Frames ................................................56
      8.5. HTML Command Subclasses ...................................58
      8.6. Information Elements ......................................58
      8.7. Media Formats .............................................86
   9. Example Message Flows ..........................................87
      9.1. Ping/Pong .................................................88
      9.2. Lagrq/Lagrp ...............................................88
      9.3. Registration ..............................................89
      9.4. Registration Release ......................................89
      9.5. Call Path Optimization ....................................90
      9.6. IAX Media Call ............................................91
      9.7. IAX Media Call via an IAX Device ..........................93
   10. Security Considerations .......................................94
   11. IANA Considerations ...........................................96
   12. Implementation Notes ..........................................96
   13. Acknowledgments ...............................................97
   14. References ....................................................97
      14.1. Normative References .....................................97
      14.2. Informative References ...................................99

1. Introduction 🌈

Okay, so here's the context 💖

Loads of protocols have been specified by the Internet community for controlling or signaling multimedia sessions 🎧. Examples are SIP [RFC3261], Media Gateway Control Protocol (MGCP) [RFC3435], and MEGACO/H.248 [RFC3525]. That last one has been obsoleted and made historic by [RFC5125] 💀. Generally, these protocols are built to fully support lots of media types. That flexibility adds some overhead to the headers, but it lets the protocol be used way beyond its original application 🧁. These protocols usually reference the media transmission protocol that carries the actual stream, but they don't specify it 👀. SIP commonly uses Session Description Protocol (SDP) [RFC4566] to describe Real-Time Transport Protocol (RTP) [RFC3550] streams. That gives a lot of flexibility, but yep, more overhead 😭. Also, multimedia solutions that use different (maybe dynamic) network addresses for signaling and media often run into NAT traversal and security challenges 🙃.

IAX is the Inter-Asterisk eXchange protocol 🎀. It makes VoIP connections between servers, and between servers and clients that also speak IAX 📞. It came from an open source methodology, not a traditional standards-based one 🌸. It's an open protocol that Asterisk originally used. Asterisk is a dual-licensed open source and commercial PBX server from Digium ✨. Independent IAX implementations can be open, proprietary, or licensed in any way the author sees fit, without royalties to the protocol's creators 💅.

1.1. Basic Properties 🦋

This is the "why IAX is special" section, and it's giving efficiency 🔥

IAX is robust and full-featured, yet still simple 🍓. It's general enough to handle most common types of media streams. But it's highly optimized for VoIP calls, where low overhead and low bandwidth consumption are the priorities 💜. That pragmatic focus makes IAX more efficient for VoIP than protocols that plan for way-out-there possibilities and specify tons of details that aren't strictly needed to describe or carry a point-to-point call 🙄. Because IAX is lightweight and VoIP-friendly, it also uses less bandwidth than more general approaches 🫶. It's a binary protocol, designed to cut overhead, especially for voice streams 🤖. Some places do trade away bandwidth efficiency, in exchange for better efficiency for individual voice calls 🧚.

Here's an example to make it click. A voice stream compressed to 8 kbit/s with 20 ms packetization has 20-byte data packets. IAX adds 20% overhead, which is 4 bytes, on most voice packets. RTP adds 60% overhead, with 12 additional bytes per voice packet 😭🔥. Bestie, that's a real difference 💖.

Next, IAX's single static UDP port makes its traffic easy for network managers to shape, prioritize, and pass through firewalls 🌈. Its basic structure multiplexes signaling and multiple media streams over a single UDP stream between two computers 💅. IAX also uses the same UDP port for both its signaling and media messages. Since all communications about a call happen over the same point-to-point path, NAT traversal is way simpler for IAX than for other commonly deployed protocols 👑✨.

1.2. Drawbacks ✨

okay so IAX is honestly SO effective and handles a lot of today's communication needs 💅, but it's not perfect, bestie 🙈 here's the tea on its limitations:

Its codec negotiation is point-to-point, which is lowkey a pain for extensibility. Every IAX node in a call path has to support every codec being used, at least to some degree 🥲. Also, the codec definition is controlled by an internally defined 32-bit mask, so codecs have to be defined in the protocol itself. That means the max number of simultaneous codecs is limited too.

IAX uses a single, well-known port, and that's one of its best design strengths, but it also makes the protocol an easier target for denial-of-service attacks 😭. Real-time systems like VoIP are especially sensitive to these attacks.

The protocol is typically deployed with all signaling and media going to one centralized server. That gives you a great deal of control, but it limits overall system scalability. The good news is that IAX now lets you split the media from the signaling stream, which overcomes this limit from earlier IAX versions 🎉.

Most IAX drawbacks are actually implementation issues, not protocol issues. Threading is the big mess here: many implementations have a limited number of threads to process IAX traffic, so they can get overwhelmed by heavy use or denial-of-service attacks. Newer implementations have extra controls to minimize the impact 🧚.


2. IAX Terminology ✨

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

Additionally, this document uses the following terminology (the glossary is open, bestie 📖):

  • Peer: A host or device that implements the IAX protocol.
  • Call: A call is a relationship between two or more parties (i.e., resources such as devices, user agents, or programs) that exists for some time for the purpose of exchanging real-time media. In the context of this document, a call is an end-to-end relationship where at least the one leg of call path is implemented using the IAX protocol.
  • Calling Party: A device or program that initiates a call.
  • Called Party: A device or program to which a call is directed.
  • Context: A context is a named partition of a Dialplan.
  • Dialplan: A Dialplan is a set of rules for associating provided names and numbers with a particular called party.
  • Frame: The atomic communication unit between two IAX peers. All IAX messages are carried within frames.
  • Information Element (IE): A discrete data unit appended to an IAX frame that specifies user- or call-specific data.
  • Registrant: A registrant is a peer that makes REGISTER requests in order to advertise the address of a resource, i.e., a device or program to which a call may be directed.
  • Registrar: A registrar is a peer that processes REGISTER requests and places the information it receives in those requests into the location service. [RFC3261]

3. Overview of IAX Protocol 🦋

IAX is a peer-to-peer, VoIP-oriented protocol. It includes both control and media functions. It can register locations, create, modify, and terminate multimedia sessions, and it can carry the actual media streams specified by the sessions it manages. The protocol is designed and optimized for describing and transporting multimedia calls using Internet Protocol. This document describes Version 2 of IAX. Version 1 was somewhat similar in design, but it used a different port and was not widely deployed.

The basic design approach for IAX multiplexes signaling and multiple media streams over a single UDP association between two hosts. It does this by using the same "well-known" UDP port, 4569, for all types of IAX traffic. IAX's unified signaling and media paths achieve NAT transparency, which is an advantage of IAX over alternative media transport protocols such as SIP [RFC3261] ✨.

IAX is coded as a binary protocol, and one major benefit of that is bandwidth efficiency. The quality of voice calls is frequently related to the amount of bandwidth consumed, so this is one way the protocol is specifically optimized to use bandwidth efficiently for individual voice calls 🎤. The bandwidth efficiency for other stream types is sacrificed for the sake of individual voice calls. Other benefits of a binary protocol are robustness against buffer-overrun attacks and a compact implementation capability, which reduces interoperability issues related to parsing 💪.

The atomic communication unit in IAX is the "Frame". There are multiple classes of Frames, each described below. In general, "Full Frames" carry signaling/control data, while "Mini Frames" carry media stream data. Full Frames enclose optional 'Information Elements' (IEs), which describe various types of user- or call-specific data. "Meta Frames" are used for call trunking or video stream transmission 🎬.

An IAX-based call may consist of many call legs, or segments. Each call leg may be implemented using different protocols, e.g., SIP to IAX to ISDN (Integrated Services Digital Network). IAX is responsible for setting up one or more legs of a complete call path, not necessarily the end-to-end call 🛤️.

IAX is an optimized peer-to-peer protocol. If two adjacent call legs use the IAX protocol, and the intermediate peer determines that it does not need to remain in the call path, it can supervise a calling path change so that it removes itself from the path. This supervision is complete: a call path is not changed until all peers in the optimized call path confirm they can properly communicate 🤝.

IAX supports security features by allowing multiple methods of user authentication and authorization, as well as multiple security methods for peer registration. IAX also specifies a generic framework for native encryption 🔐.


4. Naming Conventions 🎀

  • Call Identifier: A call leg is marked with two unique integers, one assigned by each peer involved in creating the call leg.
  • Number: The Calling and Called Numbers are a set of digits and letters identifying a call originator and the desired terminating resource. The term 'Number' is historic and has been expanded to include letters. A peer is responsible for defining its own dialplan. A peer MAY define its dialplan according to ITU-T Recommendation E.164 [E164]. However, this is not required.
  • Username: A username is a string used for identification purposes.

5. IAX Uniform Resource Identifiers 🌸

5.1. IAX URI Scheme Registration

This section registers IAX according to the guidelines in [RFC4395] 📝.

URI scheme name:

iax

Status:

Permanent.

URI scheme syntax:

The "iax:" scheme follows the guidelines in [RFC3986].

The general form is as follows:

iax:[username@]host[:port][/number[?context]]

Where these tokens have the following meanings:

  • iax:: The literal 'iax:'.
  • username: A string used for identification purposes.
  • host: The domain of the resource. The host part contains either a fully-qualified domain name or a numeric IPv4 or IPv6 address. An IPv6 address must be enclosed within brackets (i.e., '[2001:db8::1]') as defined in [RFC3986]. Using the fully-qualified domain name form is RECOMMENDED whenever possible 💖.
  • port: The numeric UDP port number.
  • number: The name or number identifying the resource on that host.
  • context: The name of the host partition in which the service is identified or processed.

Examples

iax:example.com/alice
iax:example.com:4569/alice
iax:example.com:4570/alice?friends
iax:192.0.2.4:4569/alice?friends
iax:[2001:db8::1]:4569/alice?friends
iax:example.com/12022561414
iax:johnQ@example.com/12022561414

ABNF

Formal syntax is defined using ABNF [RFC5234]. Certain values are included by reference from [RFC3986]:

iax-uri     = "iax:" [ userinfo "@" ] host [ ":" port ]
              [ "/" number [ "?" context ] ]

userinfo    = <as specified in RFC 3986>

host        = <as specified in RFC 3986>

port        = <as specified in RFC 3986>

number      = *(unreserved / sub-delims / pct-encoded )

context     = *(unreserved / sub-delims / pct-encoded )

unreserved  = <as specified in RFC 3986>

sub-delims  = <as specified in RFC 3986>

pct-encoded = <as specified in RFC 3986>

URI Scheme Semantics:

An IAX URI identifies a communications resource capable of communicating using the IAX Version 2 protocol defined in this document. Within this document, we refer to the IAX Version 2 protocol URI as IAX. An IAX URI contains enough information to initiate an IAX-based call with that resource 📞.

IAX URIs are associated with server resources to which calls may be routed. For instance, an IAX URI may represent an appearance on a phone, a voice-mail box on a messaging service, an interactive program, a Public Switched Telephone Network (PSTN) address or gateway, or any group of the above 🌈.

The IAX URI scheme translates into a location that may be used by the IAX protocol to establish a new call, using the URI scheme components described in the previous section. This new call function is the only defined operation 🎯.

Encoding considerations:

IAX URI scheme encoding conforms to the encoding rules established for URIs in [RFC3986].

Applications/protocols that use this URI scheme name:

The scheme is used by ENUM Dynamic Delegation Discovery System (DDDS) services to specify resources that support the IAX protocol. The IAX protocol provides an application-layer control and media protocol for creating, modifying, and terminating multimedia sessions over Internet Protocol (IP) networks 🌐.

Interoperability considerations:

None.

Security considerations:

⚠️ Serious security moment, bestie 🙈: The IAX URI Scheme does not introduce any new security concerns, except that it provides a uniform syntax for describing IAX resources and that, when published, these addresses are subject to various denial-of-service attacks.

Contact:

Ed Guy, edguy@emcsw.com, +1.973.437.4519.

Author/Change controller:

Not Applicable.

References:

RFC 5456 (this document)

5.2. URI Comparison ✨

Okay so, sometimes the IAX spec needs to figure out whether two IAX URIs are basically the same thing 🔍💖. Here's how it checks, bestie: all components of the URI MUST be identical except for these two things:

  • The port, if omitted, is considered to be the same as the default, 4569.
  • All URI components, except the username field, are case insensitive, and MUST be normalized to lower case as per Section 6.2.2.1 of [RFC3986] before comparison.

Here are sets of URIs that are equivalent, aka they're giving twins 👯‍♀️🎀:

iax:atlanta.com/alice
iax:AtLaNtA.com/ALicE
iax:atlanta.com:4569/alice

iax:alice@atlanta.com/alice
iax:alice@AtLaNtA.com:4569/ALicE

And this set is NOT equivalent, no cap 🙅‍♀️💅. The username casing matters here:

iax:ALICE@atlanta.com/alice
iax:alice@atlanta.com/alice
NOTE: A host in domain form and in IP address form are NOT considered identical even if the host name resolves to an address record that matches the given IP address. 🫣 So even if the names point to the same place, a domain and an IP are not the same URI in the comparison. Iykyk 😭.
  1. Peer Behavior and Related Messages 🦋

Okay, peers send messages in two flavors. Reliable ones are called "Full Frames" 💌. They have a message type indicator, stuff that makes sure they actually arrive (see Section 7, bestie), and the full call identifier, which is made of each peer's identifiers for the call. They can also carry extra attributes called "Information Elements" or "IEs" 🧩.

The non-guaranteed ones are "Mini-Frames" and "Meta Frames" 🌸. They're way more compact and only carry the originating peer's call identifier, and they MUST NOT have any "Information Elements". No extras allowed, periodt 💅.

Peer behavior is split up into these functional areas 🍓:

  • Registration (OPTIONAL)
  • Call Link Management
  • Call Path Optimization (OPTIONAL)
  • Mid-Call Behavior
  • Call Tear Down
  • Network Monitoring
  • Digit Dialing (OPTIONAL)
  • Miscellaneous
  • Media Messages

Each of these behaviors and the messages involved get their own section below, so keep reading 👀✨.

6.1. Registration (OPTIONAL) 🎀

6.1.1. Overview 💖

So, for one IAX peer to reach another, the calling peer needs the receiving peer's network address 📞. That address might be typed in manually, found in a shared directory (like an ENUM-like service, see [RFC3761]), or configured using the IAX protocol itself. IAX has a registration facility so one peer can register its address and credentials with another, so callers can find the registrant 🗺️. Registration is optional. If you do implement it, the registration protocol MAY be done in parts, e.g., an analog telephone adapter MAY only implement the registrant portion of the protocol 🧚.

IAX supports multiple ways to authenticate users 🔐. MD5 Message-Digest authentication [RFC1321] uses an MD5 sum arrangement, but it still requires both ends to have plaintext access to the secret (see Section 8.6.15) 🙈. Rivest, Shamir, and Adleman's (RSA) algorithm [RFC3447] lets only one side know the secret, using public/private key pairs 🔑. IAX Private keys SHOULD always be Triple Data Encryption Standard (3DES) encrypted [RFC1851] 💜 (see Section 8.6.16).

Here's the Registrant State Diagram, Figure 1, which is lowkey a lot but stay with me 🌈:

                     ________________
                    |                |
                    |  Unregistered  |<--------------------------\
                    |________________|                           |
                            |                                    |
              /Init         |                                    |
              ------------  |                                    |
              snd REGREQ    |    +--------+                      |
                            |    |        | rec REGAUTH          |
                     _______V____V___     | -----------          |
                    |                |    | snd REGREQ           |
                    |   Reg Sent     +----+                      |
                    |________________+----------+                |
                            |    ^              | rec REGAUTH    |
               rec REGACK   |    |              | /No Credentials|
              ------------  |    | REG timeout  | -------------- |
               snd ack      |    | -------      | snd ack        |
                            |    | REGREQ     __V___             |
                     _______V____|___        |      |            |
                    |                |       |  No  |            |
                    |   Registered   |       | Auth |            |
                    |________________|       |______|            |
                            |                   ^                |
                            |                   | rec REGAUTH    |
                            | release           | /No Credentials|
                            | -------           | -------------- |
              +-------+     | snd REGREL        | snd ack        |
 rec REGAUTH  |       |     |                   |                |
 -----------  |      _V_____V________           |                |
 snd REGREL   |     |                |----------+                |
              +-----+   Releasing    |---------------------------+
                    |________________|      rec ACK
                                            -------
                                               x

                 __________
rec  REGREJ     |          |
----------   *->| Rejected |
snd   ack       |__________|


                Figure 1: Registrant State Diagram

Registration works like this 📝: a registrant sends a username and a registration 'refresh' period to the registrar, using a REGREQ message. If authentication is needed, the registrar replies with a REGAUTH message listing which authentication types it supports 🛡️. Then the registrant resends a REGREQ using one of those authentications. If the registrant can't authenticate, nothing else needs to happen 🙃. If it's accepted, the registrar sends a REGACK message, which MUST indicate the 'apparent address' and SHOULD indicate the 'refresh'/expire time ⏰. If no 'refresh' is sent, both peers MUST assume a default registration expiration of 60 seconds ⏳. At any point in this exchange, the registrar may send a REGREJ message to say something failed 💀.

A registration has a time period that it's valid for 🗓️. That period starts when the registrar sends a REGACK message. A registrant can extend the time period by repeating the registration process 🔄. A registrant MAY also force an expiration in the registrar by sending the REGREL message 🚪. That message might get challenged with REGAUTH, or if the right credentials were included, it gets accepted with REGACK ✅. When a REGAUTH comes back, the REGREL SHOULD be resent using the specified credentials 💫.

See Sections 9.3 and 9.4 for example call flows 📚✨.

6.1.2. REGREQ Registration Request Message 📨

The REGREQ happens independently of any media-carrying call 🎧. A REGREQ MUST include the 'username' IE and SHOULD include the 'refresh' IE. It's used both for the first registration request and as a reply to a REGAUTH. When it's a reply to a REGAUTH, it MUST include credentials, like a response to the REGAUTH's challenge 🔏.

When a registrar gets a REGREQ with credentials, it MUST check whether they're valid 🕵️‍♀️. If they are, it MUST respond with a REGACK message indicating the time period for which this registration is valid 🎉. If the credentials aren't valid, or the registrar can't validate them, the registrar MUST respond with a REGREJ message 🙅‍♀️. If no credentials are provided, the registrar MUST respond with a REGAUTH message that lists the available authentication methods 📋.

Registrants MUST implement this message, and registrars MUST be able to process it 💪.

The following table specifies IEs for this message 📊:

    +------------+----------------+-------------+-------------+
    | IE         | Section        | Status      | Comments    |
    +------------+----------------+-------------+-------------+
    | Username   | Section 8.6.6  | Required    |             |
    |            |                |             |             |
    | MD5 Result | Section 8.6.15 | Conditional | per REGAUTH |
    |            |                |             |             |
    | RSA Result | Section 8.6.16 | Conditional | per REGAUTH |
    |            |                |             |             |
    | Refresh    | Section 8.6.18 | Optional    |             |
    +------------+----------------+-------------+-------------+

6.1.3. REGAUTH Registration Authentication Response Message 🎀

A REGAUTH is a response to a REGREQ or REGREL 💞. It's sent when a registrar requires authentication before it allows registration. A REGAUTH message MUST include the 'authentication methods' and 'username' IEs, plus the 'MD5 challenge' or 'RSA challenge' IE if the authentication methods include MD5 or RSA 🔐.

When a registrant gets a REGAUTH message, it MUST resend the REGREQ or REGREL message with one of the requested credentials, if it has the specified credentials 🔁.

Registrars MUST implement this message, and registrants MUST be able to process it 🫶.

The following table specifies IEs for this message 📋:

      +--------------+----------------+-------------+---------------+
      | IE           | Section        | Status      | Comments      |
      +--------------+----------------+-------------+---------------+
      | Username     | Section 8.6.6  | Required    |               |
      |              |                |             |               |
      | Auth Methods | Section 8.6.13 | Required    |               |
      |              |                |             |               |
      | Challenge    | Section 8.6.14 | Conditional | If RSA or MD5 |
      +--------------+----------------+-------------+---------------+

6.1.4. REGACK Registration Acknowledgment Message

okay bestie, the REGACK is the reply you send back to a REGREQ 💌✨ it typically carries the 'refresh' IE, which tells everyone how many seconds the registration lasts before it expires ⏰. if there's no 'refresh' IE in the REGACK, then a default registration expiration of 60 seconds MUST be assumed 💅. it MAY also include the 'username' and 'apparent address' IEs so everyone knows how the peer sees the registrant 🦋, and caller identification info or the time the registration happened MAY be sent too 🌸

getting a REGACK means you have to send an ACK back 🫶 registrars MUST be able to send this message, and registrants MUST be able to process it. iconic teamwork 👑

here's the IE table:

+------------------+----------------+----------+----------+
| IE               | Section        | Status   | Comments |
+------------------+----------------+----------+----------+
| Username         | Section 8.6.6  | Required |          |
|                  |                |          |          |
| Date Time        | Section 8.6.28 | Required |          |
|                  |                |          |          |
| Apparent Address | Section 8.6.17 | Required |          |
|                  |                |          |          |
| Message Count    | Section 8.6.23 | Optional |          |
|                  |                |          |          |
| Calling Number   | Section 8.6.2  | Optional |          |
|                  |                |          |          |
| Calling Name     | Section 8.6.4  | Optional |          |
|                  |                |          |          |
| Refresh          | Section 8.6.18 | Optional |          |
+------------------+----------------+----------+----------+

6.1.5. REGREJ Registration Rejection Message

a REGREJ is the "nope, not today" message 🙅‍♀️ it means a registration request got rejected, and that can happen for several reasons. a REGREJ MUST include the 'causecode' and 'cause' IEs so everyone knows exactly why it was rejected 🔍

when a REGREJ comes in, the registrant MUST treat the registration process as unsuccessful, and no further interaction is needed 🛑 a peer MAY try again later, taking into account possible configuration changes on the registrar or registrant 🔄 both registrants and registrars MUST be capable of sending and processing this message. we love a fair system 🌈

here's the IE table:

+------------+----------------+----------+----------+
| IE         | Section        | Status   | Comments |
+------------+----------------+----------+----------+
| Cause      | Section 8.6.21 | Required |          |
|            |                |          |          |
| Cause Code | Section 8.6.33 | Required |          |
+------------+----------------+----------+----------+

6.1.6. REGREL Registration Release Request Message

a REGREL is how a registrant forces a prior registration to be released 🗑️ it MUST include the 'username' IE to identify the registrant being released, and MAY include the 'causecode' and 'cause' IEs to explain why the registration is being released 💬

when this message arrives, a peer MUST authenticate the sender using the provided credentials, or send a REGAUTH message asking for them 🔐 once they're authenticated, the peer MUST immediately purge its registration of the specified registrant, or send a REGREJ message if the registration can't be found 🧹 main character energy for the security checks, ngl 💅

registrants SHOULD be capable of sending this message, and registrars MUST be able to process it ✨

here's the IE table:

+----------+----------------+-------------+-------------------------+
| IE       | Section        | Status      | Comments                |
+----------+----------------+-------------+-------------------------+
| Username | Section 8.6.6  | Required    |                         |
|          |                |             |                         |
| MD5      | Section 8.6.15 | Conditional | MD5 or RSA Result is    |
| Result   |                |             | required                |
|          |                |             |                         |
| RSA      | Section 8.6.16 | Conditional |                         |
| Result   |                |             |                         |
|          |                |             |                         |
| Cause    | Section 8.6.21 | Optional    |                         |
|          |                |             |                         |
| Cause    | Section 8.6.33 | Optional    |                         |
| Code     |                |             |                         |
+----------+----------------+-------------+-------------------------+

6.2. Call Leg Management

okay now we're getting into the call leg glow-up 🦋 these state diagrams show how a call moves through its states, from the first NEW message all the way to hanging up 📞

                                          +--------+  HANGUP/ack
                                          |        |
                             _____________|__      |
                            |                |     |
                 +--------->|    Initial     |<----+
                 |          |________________|<---------------------+
                 |                  |                               ^
                 |       start call |                               |
                 |       ---------- |                               |
                 |       send NEW   |  +-------+                    |
                 |                  |  |       |  rec AUTHREQ       |
                 |             _____V__V__     |  -----------       |
                 |            |           |    |  snd AUTHREP       |
                 +------------|  Waiting  |----+                    |
         rec REJECT           |___________|------------------------>+
         ----------                  |                              |
           ack                       |              rec HANGUP      |
                                     |              ---------       |
                                     |              snd ack         |
                                     |                              |
                       rec ACCEPT    |                              |
                       ----------    |   +------+                   |
                       snd ack       |   |      | PROCEEDING / ack  |
                            _________V___V      | RINGING / ack     |
                           |              |     |                   |
                           |     Linked   |-----+                   |
                           |______________|------------------------>+
                                    |               rec HANGUP      |
                       rec ANSWER   |               ----------      |
                       -----------  |               snd ack         |
                       snd ack      |                               |
                                    |                               |
                                    |               rec HANGUP      |
                             _______V________       ---------       |
                            |                |      snd ack         |
                            |      UP        |--------------------->+
                            |________________|--------------------->+
                                                    finish
                                                    ------
                                                    snd HANGUP


                 Figure 2: Call Origination State Diagram
                                 +--------+ rec HANGUP/ack
                                 |        |
                    _____________V__      | rec NEW(no Auth)/snd AUTHREQ
                   |                |     |
                   |    Initial     |-----+ rec NEW(not Auth)/snd REJECT
                   |                |
                   |________________|<--------------------+
                           |                              |
             rec NEW       |                              |
        (valid credentials)|                              |
             ----------    |   +------+                   |
             snd ACCEPT    |   |      | snd PROCEEDING    |
                  _________V___V      | snd RINGING       |
                 |              |     |                   |
                 |     Linked   |-----+                   |
                 |              |
                 |______________|------------------------>+
                          |               rec HANGUP      |
              /answered   |               ----------      |
             -----------  |               snd ack         |
             snd ANSWER   |                               |
                          |               rec HANGUP      |
                   _______V________       ---------       |
                  |                |       snd ack        |
                  |      UP        |--------------------->+
                  |________________|--------------------->+
                                          finish
                                          ------
                                          snd HANGUP


                 Figure 3: Call Termination State Diagram

6.2.1. Overview

so the IAX protocol can set up 'links' or 'call legs' between two peers so you can place a call 📞🌸 the whole thing, shown in Figure 2 and Figure 3, kicks off when a peer sends a NEW message with the destination 'number' (or name) of a Called Party on the remote peer 💜

the remote peer can answer with a credentials challenge (AUTHREQ), a REJECT message, or an ACCEPT message 🎀 the AUTHREQ message says which authentication schemes are allowed, and it SHOULD lead to an AUTHREP message carrying the requested credentials 🔑 a REJECT means the call can't be set up right now 🙅‍♀️ and ACCEPT means the call leg between these two peers is established, so higher-level call signaling (Section 6.3) MAY go ahead 🚀

once the ACCEPT is sent or received, the call leg is in the 'Linked' state and it's used to pass call control messages until the call wraps up 🦋 you can find more detail on those messages in Section 6.3 ✨

call legs get labeled with a pair of identifiers 🏷️ each end of the call leg assigns the source or destination identifier while the call leg is being created 💖

6.2.2. NEW Request Message ✨

okay bestie, the NEW message is how a call gets started 📞 It's the first call-specific message that actually kicks off a media exchange between two peers. NEW messages are kind of iconic compared to the other Call Supervision messages because they don't need a destination call identifier in their header 💅 That's because the remote peer hasn't created its source call identifier yet. It only shows up after the frame lands 🦋 So before sending a NEW, the local IAX peer MUST assign a source call identifier that isn't already being used for another call. A time-stamp MUST also be assigned for the call, starting at zero and going up by one every millisecond ⏱️ And the sequence numbers for a NEW are both set to 0. (The transport section, Section 7, has the details on those.) 🌸

A NEW message MUST include the 'version' IE, and it MUST be the first IE. The order of the other IEs isn't specified, so you're free to mix those up 🎀 A NEW SHOULD generally include IEs that tell the remote peer where to route, like the 'called number' IE, or the 'called context' IE for a peer partition or ruleset 🧚 Caller identification and CODEC negotiation IEs MAY also be included. ✨

When a NEW message comes in, the receiving peer looks at the destination and MUST do one of these things: 👑

  • Send a REJECT response,
  • Challenge the caller with an AUTHREQ response,
  • Accept the call using an ACCEPT message, or
  • Abort the connection using a HANGUP message, although the REJECT message is preferred at this point in the call.

If the call is accepted, the peer MUST keep the call moving and respond with one of PROCEEDING, RINGING, BUSY, or ANSWER, depending on what's going on with the called party on that peer 📲 See Section 6.3 for the full tea. 🫶

Here's the IE table for the NEW message. Keep an eye on the Status column, it's where the drama is 🙈

+--------------+----------------+-------------+---------------------+
| IE           | Section        | Status      | Comments            |
+--------------+----------------+-------------+---------------------+
| Version      | Section 8.6.10 | Required    |                     |
|              |                |             |                     |
| Called       | Section 8.6.1  | Required    |                     |
| Number       |                |             |                     |
|              |                |             |                     |
| Auto Answer  | Section 8.6.24 | Optional    |                     |
|              |                |             |                     |
| Codecs Prefs | Section 8.6.35 | Required    |                     |
|              |                |             |                     |
| Calling      | Section 8.6.29 | Required    |                     |
| Presentation |                |             |                     |
|              |                |             |                     |
| Calling      | Section 8.6.2  | Optional    |                     |
| Number       |                |             |                     |
|              |                |             |                     |
| Calling TON  | Section 8.6.30 | Required    |                     |
|              |                |             |                     |
| Calling TNS  | Section 8.6.31 | Required    |                     |
|              |                |             |                     |
| Calling Name | Section 8.6.4  | Optional    |                     |
|              |                |             |                     |
| ANI          | Section 8.6.3  | Optional    |                     |
|              |                |             |                     |
| Language     | Section 8.6.9  | Optional    |                     |
|              |                |             |                     |
| DNID         | Section 8.6.12 | Optional    |                     |
|              |                |             |                     |
| Called       | Section 8.6.5  | Conditional | 'Default' assumed   |
| Context      |                |             | if IE excluded      |
|              |                |             |                     |
| Username     | Section 8.6.6  | Optional    |                     |
|              |                |             |                     |
| RSA Result   | Section 8.6.16 | Conditional | If challenged with  |
|              |                |             | RSA                 |
|              |                |             |                     |
| MD5 Result   | Section 8.6.15 | Conditional | If challenged with  |
|              |                |             | MD5                 |
|              |                |             |                     |
| Format       | Section 8.6.8  | Required    |                     |
|              |                |             |                     |
| Capability   | Section 8.6.7  | Conditional |                     |
|              |                |             |                     |
| ADSICPE      | Section 8.6.11 | Optional    |                     |
|              |                |             |                     |
| Date Time    | Section 8.6.28 | Optional    | Suggested           |
|              |                |             |                     |
| Encryption   | Section 8.6.34 | Optional    |                     |
|              |                |             |                     |
| OSP Token    | Section 8.6.42 | Optional    |                     |
+--------------+----------------+-------------+---------------------+

6.2.3. ACCEPT Response Message 💖

an ACCEPT is the response you send once a NEW has arrived and authentication has happened (if it was needed) 🔐 It basically says "got your NEW!" and "the call leg is set up on my end, and I've picked a CODEC" 🎧 An ACCEPT MUST include the 'format' IE so the originating peer knows which CODEC is wanted. And the CODEC format MUST be one of the formats that were sent in the NEW it's answering. no surprises allowed 🙅‍♀️

When an ACCEPT is received, an ACK MUST be sent back. The CODEC for the call MAY be configured using the 'format' IE from that ACCEPT ✨ After that, the call just waits for an ANSWER, HANGUP, or some other call control signal. (See Section 6.3.) If another ACCEPT shows up for a call that's already started, or for a call that never sent a NEW, it MUST be ignored. just bounce it, no drama 💅

Here's the IE table for this one:

         +--------+---------------+----------+----------+
         | IE     | Section       | Status   | Comments |
         +--------+---------------+----------+----------+
         | Format | Section 8.6.8 | Required |          |
         +--------+---------------+----------+----------+

6.2.4. REJECT Response Message 🙅‍♀️

a REJECT is what you send when a NEW, AUTHREP, DIAL, or ACCEPT request gets turned down 💀 It MAY happen because of an authentication failure, an invalid username, or if the peer can't come up with a valid password or response to a challenge. It MAY also be used to tell a peer that call setup failed, like when the IAX peers can't agree on a CODEC to use 🎧 When a REJECT lands, the call leg is destroyed and there's nothing else to do. (Fun fact, because it's so important: REJECT messages require an explicit ACK. 🫶)

REJECT messages MAY include the 'causecode' and 'cause' IEs to explain why the call got rejected 🌈

The IE table for this message:

           +------------+----------------+----------+----------+
           | IE         | Section        | Status   | Comments |
           +------------+----------------+----------+----------+
           | Cause      | Section 8.6.21 | Optional |          |
           |            |                |          |          |
           | Cause Code | Section 8.6.33 | Optional |          |
           +------------+----------------+----------+----------+

6.2.5. HANGUP Request Message 📴

a HANGUP is sent by either peer to say "bye, the call's over" 👋 It MAY include the 'causecode' and 'cause' IEs to say why the call is ending 🌸 When a HANGUP comes in, the IAX peer MUST respond right away with an ACK, and then destroy the call leg on its end. After a HANGUP has been received for a call leg, any message that references that call leg (meaning it has the same source/destination call identifiers) MUST be answered with an INVAL message. That INVAL just means "this message is invalid, because the call doesn't exist anymore" 🦋

And after sending a HANGUP, the sender MUST destroy the call and reply to any later messages about it with an INVAL too. ghosted, but make it protocol 👻

The IE table for this message:

           +------------+----------------+----------+----------+
           | IE         | Section        | Status   | Comments |
           +------------+----------------+----------+----------+
           | Cause      | Section 8.6.21 | Optional |          |
           |            |                |          |          |
           | Cause Code | Section 8.6.33 | Optional |          |
           +------------+----------------+----------+----------+

6.2.6. AUTHREP Authentication Reply Message 🔑

an AUTHREP MUST include the right challenge response or password IE, and it's only sent in response to an AUTHREQ 🎀 An AUTHREP needs to get back either an ACCEPT or a REJECT.

Some typical reasons an AUTHREP gets rejected are 'destination does not exist' and 'suitable bearer not found' 🙈

Here's the IE table:

         +------------+----------------+-------------+----------+
         | IE         | Section        | Status      | Comments |
         +------------+----------------+-------------+----------+
         | RSA Result | Section 8.6.16 | Conditional | If RSA   |
         |            |                |             |          |
         | MD5 Result | Section 8.6.15 | Conditional | If MD5   |
         +------------+----------------+-------------+----------+

6.2.7. AUTHREQ Authentication Request Message 🛡️

the AUTHREQ gets sent in response to a NEW when the call needs authentication before it can be accepted 🔐 It MUST include the 'authentication methods' and 'username' IEs, plus the 'challenge' IE if MD5 or RSA authentication is the method being asked for 🧁

When an AUTHREQ is received, the receiver MUST respond with either an AUTHREP or a HANGUP. ✨

The IE table for this message:

          +--------------+----------------+----------+----------+
          | IE           | Section        | Status   | Comments |
          +--------------+----------------+----------+----------+
          | Username     | Section 8.6.6  | Required |          |
          |              |                |          |          |
          | Auth Methods | Section 8.6.13 | Required |          |
          |              |                |          |          |
          | Challenge    | Section 8.6.14 | Required |          |
          +--------------+----------------+----------+----------+

6.3. Call Control 🎀

6.3.1. Overview ✨

okay so IAX's call control messages are the end-to-end signaling bits that basically every other telephony control protocol has too 💅 The squad includes RINGING, ANSWER, BUSY, and PROCEEDING. These messages MUST only be sent after an IAX call leg has been ACCEPTed. no cap, that's the rule 🫶

When a call starts with a NEW message, the first call control message is usually RINGING 🔔 but a PROCEEDING message MAY show up before it, or the call MAY skip straight to the ANSWER message 💖 If the call gets picked up, an ANSWER message will be sent 🎀 Other possibilities include a "BUSY" indication 📵 or, if the called party's service can't be reached, the call gets torn down with the link-level HANGUP and an appropriate cause code 💀

If the link was started with a DIAL message, the sequence is an optional PROCEEDING, then optional RINGING, then ANSWER or BUSY 🧚 Of course, a link level HANGUP MAY occur at any time, because that's just life 🙈

Various private extensions to IAX Control messages have been deployed for passing application-specific data over the IAX control link ✨ One iconic example is an app that controls ham radio transceivers 📻 An IAX peer that receives a control message it doesn't understand MUST respond with the UNSUPPORT message 🚫

The mandatory IAX control messages are explained below 🌈

6.3.2. PROCEEDING Response Message

The PROCEEDING message SHOULD be sent to a calling party when their call request is being processed by a further network element but hasn't reached the called party yet ⏳

Once a peer gets a PROCEEDING message, it SHOULD do protocol-specific stuff to let the calling party know, like tones or an ISUP (ISDN User Part) Proceeding message, etc. 🎶 If the prior call leg is using the IAX protocol, a PROCEEDING message MUST be sent to that peer 🫶 How an originating or transcoding peer handles this message isn't specified, but if it's possible, the status may be displayed to the calling party 👀

The PROCEEDING message does not require any IEs 💅

6.3.3. RINGING Response Message

This message is sent from a terminating party to say that the called party's service has processed the call request and is being alerted to the call 🔔 An IAX RINGING message MUST be sent to an IAX-based calling party when the peer figures out that the called party is being alerted, like when their phone is ringing 📞

Once an IAX RINGING message lands, the peer MUST pass this indication to the calling party, unless the calling party has already gotten one 🙌 For an initiating peer, this is usually done by starting the ring-back tone 🎵 but lots of implementations start ring-back before ringing so it matches what users expect 🥹 If the calling party is using the IAX protocol, a RINGING message MUST be passed to this caller 💜

The RINGING message does not require any IEs ✨

6.3.4. ANSWER Response Message

This message is sent from the called party to say they accepted the call request and are talking with the calling party 🥂 Once this message is received, any ring-back or other progress tones MUST be terminated, and the communications channel MUST be opened 🌸 main character moment for sure 👑

The ANSWER message does not require any IEs 🦋

6.4.1. FLASH Request Message

The FLASH message is sent to signal a mid-call feature 📲 What it means is system dependent, and if it isn't expected, it SHOULD be ignored 🙃 Typically, this message only comes from analog telephone adapters when there's a brief circuit interruption during an answered call 🍓

The FLASH message does not require any IEs 💅

6.4.2. HOLD Request Message

The HOLD message is sent to make the remote system stop transmitting audio on this channel, and optionally swap the audio for music or other sounds 🎶 If the remote system can't do this, it SHOULD be ignored 🤷‍♀️

The HOLD message SHOULD only be sent in IAX calls that were started using the DIAL message 📞

The HOLD message does not require any IEs 🧚

6.4.3. UNHOLD Request Message

The UNHOLD message is sent to make the remote system resume transmitting audio on this channel ▶️ If the remote system can't do this, it SHOULD be ignored 🙈

The UNHOLD message SHOULD only be sent in IAX calls after the HOLD message 🔁

The UNHOLD message does not require any IEs 💜

6.4.4. QUELCH Request Message

The QUELCH message is sent to make the remote peer squelch, or stop transmitting audio on this channel 🤫 It MAY replace the audio sent to the further party with music or other sounds 🎵 If the remote system can't do this, it SHOULD be ignored 🙏

The QUELCH message MUST only be sent in IAX calls after an ACCEPT is sent or received 🔐 It SHOULD only be used on calls that were started using the NEW message 🆕

The QUELCH message does not require any IEs ✨

6.4.5. UNQUELCH Request Message

The UNQUELCH message is sent to make the remote system resume transmitting audio on this channel 🔊 If it had replaced the audio with music or other sounds, it MUST discontinue that immediately 🛑 If the remote system can't do this, it SHOULD be ignored 🫠

The UNQUELCH message SHOULD only be sent in IAX calls after the QUELCH message 🔄

The UNQUELCH message does not require any IEs 🌈

6.4.6. TRANSFER Request Message

The TRANSFER message makes the receiving peer restart the call using another specified number 📱 The receiving peer MUST be on the calling side of this call leg, and the new call behavior is unspecified 🤔 After processing this message, a HANGUP message SHOULD be sent and the call leg torn down 👋

When sending a TRANSFER message, the new number the call is being transferred to MUST be included in the CALLED_NUMBER IE, and a CALLED_CONTEXT IE MAY be included 💅 The call leg MUST NOT be used for anything else and MAY be torn down 🧹

The following table specifies IEs for this message 📋

   +-----------+---------------+----------+----------------------------+
   | IE        | Section       | Status   | Comments                   |
   +-----------+---------------+----------+----------------------------+
   | Called    | Section 8.6.1 | Required |                            |
   | Number    |               |          |                            |
   |           |               |          |                            |
   | Called    | Section 8.6.5 | Optional | Use this IE if context is  |
   | Context   |               |          | other than default.        |
   +-----------+---------------+----------+----------------------------+

6.5. Call Path Optimization 🦋

If a peer is handling a call between two other IAX peers and it no longer needs to monitor the progress, content, or duration of the call, it MAY remove itself from the call by directing the other two peers to communicate directly 🧚 This call path optimization, or "supervised transfer", is done in a way that makes sure the call won't be lost in the process 🫶 The initiating peer doesn't let go of control until it has confirmed the other two peers are communicating 💪 Note: the parties in the call are not aware of this operation, because it's purely a network operation 🤫

                                 ________________
        rec  TXREJ              |                |     rec TXREL
        ----------   *--------->|      None      |<-----------------+
        snd  TXREJ              |________________|        ack       ^
        to other                  |           |                     |
                                  |           V                     |
                                  |                                 |
                                  |           *   (From All)        |
                   /Init Transfer |           | rec TXREQ           |
                    ------------  |           | ---------           |
                      snd TXREQ   |           | snd TXCNT           |
                      to both     |           |                     |
                                 _v___________v__                   |
                                |                |                  |
                                |     Begin      |----------------->+
                                |________________|                  |
                                  |           |                     |
                        rec TXACC |           | rec TXREADY         |
                        --------- |           | ---------           |
                      snd TXREADY |           |     x               |
                                  |           |                     |
                                 _v___________v__                   |
                                |                |----------------->+
                      ----------|     Ready      |----------        |
                     |          |________________|          |       |
                     |                   |                  |       |
     /Both Legs Ready|   /Both Legs Ready|       rec TXMEDIA|       |
   and not media-only|    and media-only |                  |       |
       ------------  |    ------------   |       -----------|       |
       snd TXREL     |     snd TXMEDIA   |            x     |       |
                     |                   |                  |       |
                 ____V____          _____V___            ___V_____  |
                |         |        |         |          |         | |
                | Release |        |  Media  |          | Media   | |
                |_________|        |_________|          |  Pass   | |
                                         |              |_________| |
                                         |                  |       |
                                         V                  V       |
    rec  TXCNT                           +------------------------->+
    ----------  (In any state)
    snd  TXACC

              Figure 4: Call Path Optimization State Diagram

When a peer starts this procedure, both call legs MUST be in the UP state, meaning they MUST have sent or received the ACCEPT message for that call leg 🔑 To kick things off, it sends a TXREQ message with the addresses and info from the other remote peers to each of its neighbors 📨 If they can do this procedure, they start transmitting all channel information to both the initiating peer and the new remote peer 🎙️ They also send a TXCNT message with packet counts for the call leg to the new remote peer 🔢 Each TXCNT message gets acknowledged with a TXACC message ✅ The peers respond by sending a TXREADY message to the initiator, letting it know they've confirmed the new communications path 🥳 Once all remote peers have sent the initiator a TXREADY message, the transfer is successful, and the initiator responds with a TXREL and is done with its involvement in the call 🎉 If the two remote peers can't communicate during the transfer, they send a TXREJ message to the initiator 🥺 An example is shown in Section 9.5 📖

These messages are described in the sections that follow 💖

6.5.1. TXREQ Transfer Request Message 📞✨

okay so the TXREQ is the message a peer sends to kick off the transfer process 💅 and when it goes out, it MUST be sent to both adjacent peers involved in the call, no exceptions bestie 🫶

It MUST include these Information Elements:

     +------------------+----------------+----------+----------+
     | IE               | Section        | Status   | Comments |
     +------------------+----------------+----------+----------+
     | Apparent Address | Section 8.6.17 | Required |          |
     |                  |                |          |          |
     | Call Number      | Section 8.6.20 | Required |          |
     |                  |                |          |          |
     | Transfer ID      | Section 8.6.26 | Required |          |
     +------------------+----------------+----------+----------+

So the Apparent Address is the IP address data structure address for the other remote peer 🗺️ The Call Number IE is the callid used by that other remote peer, and the Transfer ID is a unique number the initiator assigns 🔢

Here's the vibe check: when a peer gets a TXREQ for a valid call from the matching remote peer, it MUST respond by actually trying to talk to the new peer 📡 It does this by sending a TXCNT message straight to the address in the Apparent Address parameter. main character energy 💜

6.5.2. TXCNT Transfer Connectivity Response Message 🔥

The TXCNT message is how peers check that they can actually reach a potential replacement peer for a call 🕵️‍♀️ It MUST include the TRANSFERID IE. When a peer gets one of these, and it has already received a TXREQ for this call leg, it MUST respond with a TXACC message.

Now the important bit 👀 If the TXCNT doesn't get sent successfully, or no TXACC comes back in response, the transfer process MUST be aborted by sending a TXREJ message to the initiating host. Not me getting stuck in limbo 💀

It MUST include the following Information Element:

   +----------+----------------+----------+----------------------------+
   | IE       | Section        | Status   | Comments                   |
   +----------+----------------+----------+----------------------------+
   | Transfer | Section 8.6.26 | Required | A unique number assigned   |
   | ID       |                |          | by the initiator.          |
   +----------+----------------+----------+----------------------------+

6.5.3. TXACC Response Message 🦋

Like the TXCNT, the TXACC message is also used to verify connectivity with a potential replacement peer 🤝 It MUST include the TRANSFERID IE. When a peer receives one of these while it's attempting to transfer this call leg, it stops sending call-related media to the initiating peer and sends a TXREADY message to it. Quiet down the media, we're transferring 🤫✨

It MUST include the following Information Element:

   +----------+----------------+----------+----------------------------+
   | IE       | Section        | Status   | Comments                   |
   +----------+----------------+----------+----------------------------+
   | Transfer | Section 8.6.26 | Required | A unique number assigned   |
   | ID       |                |          | by the initiator.          |
   +----------+----------------+----------+----------------------------+

6.5.4. TXREADY Transfer Ready Response Message 🌸

The TXREADY message says that the sending peer has checked that it can reach the peer it was told to transfer the call to 🙌 It MUST include the TRANSFERID IE. Once TXREADY messages have come in from both remote peers, it MUST discontinue media transport and send a TXREL message to each peer. ready, set, release 🍑

It MUST include the following Information Element:

   +----------+----------------+----------+----------------------------+
   | IE       | Section        | Status   | Comments                   |
   +----------+----------------+----------+----------------------------+
   | Transfer | Section 8.6.26 | Required | A unique number assigned   |
   | ID       |                |          | by the initiator.          |
   +----------+----------------+----------+----------------------------+

6.5.5. TXREL Transfer Release Response Message 💖

The TXREL message means the transfer process has successfully completed 🎉 After it's sent and received, no more back-and-forth is needed between the peers on this call leg (other than an ACK, obviously 🙄). The TXREL also gets used to revert a split-media call, meaning one where the media and signaling take different paths, back into a call where both follow the same path 🔁

It MUST include the following Information Element:

          +-------------+----------------+----------+----------+
          | IE          | Section        | Status   | Comments |
          +-------------+----------------+----------+----------+
          | Call Number | Section 8.6.20 | Required |          |
          +-------------+----------------+----------+----------+

6.5.6. TXMEDIA Transfer Media Message 🎀

The TXREL message indicates that the MEDIA transfer process has successfully completed 🌈 After it's sent and processed, Full Frames MUST continue to follow the original signaling path, and media frames MUST follow the newly negotiated path. This split-path setup keeps going until the call ends with a HANGUP, or until a peer receives a TXREL message for the call leg. A peer MAY force the paths to rejoin by sending a TXREL message. Two paths, one call, a lot of drama 🧚

It MUST include the following Information Element:

          +-------------+----------------+----------+----------+
          | IE          | Section        | Status   | Comments |
          +-------------+----------------+----------+----------+
          | Call Number | Section 8.6.20 | Required |          |
          +-------------+----------------+----------+----------+

6.5.7. TXREJ Transfer Rejection Response Message 🚫

The TXREJ MAY be sent at anytime during the transfer process to say the transfer can't go ahead 🙅‍♀️ When a TXREJ comes in, and the receiver is the initiating peer, it MUST form a TXREJ message and send it to the other remote peer. Bounce-back energy, iconic 😭

The TXREJ message does not require any IEs.


6.6. Call Tear Down 💀

The messages used to finish a call change depending on which process the call is in at the time 🌙 The terminal messages for a call are:

  • HANGUP. See Section 6.2.5.
  • REJECT. See Section 6.2.4.
  • TRANSFER. See Section 6.4.6.
  • TXREADY. See Section 6.5.4.

These messages are discussed in their respective sections 📚 Also, if the reliable transport procedures determine that messaging cannot be maintained, the call leg MUST be torn down without any other indications over the errant IAX call leg. Rip, but make it make sense 😭🥀


6.7. Network Monitoring 📊

The IAX protocol has a bunch of tools for figuring out the network load 🧐 It uses the POKE message to monitor whether a remote peer is reachable, and the LAGRQ message to measure the quality of a current call leg, including the jitter buffer delay. Checking the vibes on the network, literally 🌸

6.7.1. POKE Request Message 🧚

A POKE message is sent to test connectivity of a remote IAX peer. It's similar to a PING message, except that it MUST be sent when there is no existing call to the remote endpoint. It MAY also be used to "qualify" a user to a remote peer, so that the remote peer can keep track of the state of the user 👀 A POKE MUST have 0 as its destination call number. Zero is the vibe here 0️⃣

Upon receiving a POKE message, the peer MUST respond with a PONG message.

This message does not require any IEs.

6.7.2. PING Request Message 🏓

A PING message is sent to test connectivity of the remote IAX endpoint on an existing call. Sending a PING MAY happen when a peer-defined number of seconds has gone by without an incoming media frame on a call, or by default every 20 seconds ⏰ Getting a PING requires an acknowledging PONG to be sent back. Ping, pong, ping, pong, the whole ✨ rhythm 💅

This message does not require any IEs.

6.7.3. PONG Response Message 🏓

A PONG message is a response to a PING or a POKE, and it acknowledges the connection 🫶 The receiver uses the time-stamp of the received PING or POKE, plus its own times, to figure out the Round Trip Time of the connection ⏱️ Several receiver report IEs MAY be included with a PONG, including received jitter, received frames, delay, and dropped frames 📈 Getting a PONG requires an ACK.

This message does not require any IEs.

6.7.4. LAGRQ Lag Request Message 🐢

A LAGRQ is a lag request, sent to figure out the lag between two IAX endpoints. That includes how long it takes to process a frame through a jitter buffer, if there is one 🫧 It requires a clock-based time-stamp, and it MUST be answered with a LAGRP, which MUST echo the LAGRQ's time-stamp. The peer that sent the LAGRQ can compute the lag between the two peers by comparing the LAGRQ's time-stamp with the time the LAGRP was received. Math, but cute 🧮💖

This message does not require any IEs.

6.7.5. LAGRP Lag Response Message 🐌

A LAGRP is a lag reply, sent in response to a LAGRQ message. It MUST send back the same time-stamp it received in the LAGRQ, after passing the received frame through any jitter buffer the peer has configured 🎀

This message does not require any IEs.


6.8. Digit Dialing 📱

Digit Dialing support is an optional part of the IAX protocol, built for devices that don't keep their own dial plans, like analog telephone adapters, or ATAs 📞 The dialing portion of the IAX protocol MAY be implemented on the client/phone side, the server side, or not at all. The exchanges work as a series of Dialing Plan requests (DPREQs), each followed by a response (DPREP) that says whether additional digits SHOULD be collected before the call gets sent. The sections that follow break down these messages and the rules that go with them 🧚‍♀️✨

6.8.1. DPREQ Dial Plan Request Message ☎️

A DPREQ is a request for the server to analyze the called number that was passed in and figure out whether there's a valid dialing pattern on the remote peer 🔍 It MUST include the 'called number' IE to specify which extension is being queried. This command is for when a local peer doesn't handle its own dialplan or extension switching. The local peer can ask, as a user dials, how the remote peer sees the 'called number' 👀 If a DPREP comes back saying the number is valid, a DIAL MAY be sent.

This message MAY be sent by the client, and it MUST be implemented on servers that provide IAX dialing support 💜

It MUST include the following Information Element:

          +-------------+----------------+----------+----------+
          | IE          | Section        | Status   | Comments |
          +-------------+----------------+----------+----------+
          | Call Number | Section 8.6.20 | Required |          |
          +-------------+----------------+----------+----------+

6.8.2. DPREP Dial Plan Response Message ✨

okay so a DPREP is the reply to a DPREQ 💅 It tells you the status of the dialplan entry that got asked about in the 'called number' IE of the DPREQ. It MUST include the 'called number', 'dpstatus', and 'refresh' IEs. The called number is the exact same one from the 'called number' IE of the DPREQ. The 'dpstatus' IE is the status of the dialplan entry for that called number, so it tells you if the number exists, can exist, needs more digits, or is invalid 🔍 More deets are in Section 8.6 under the DPSTATUS information element. The 'refresh' IE says how many minutes the 'dpstatus' stays valid. If 'refresh' isn't there, a default 10 minute period is assumed ⏰

Servers that support IAX dialing MUST implement the sending of this message 🖥️ Clients that support IAX dialing MUST be capable of receiving these messages 💜

It MUST include the following Information Elements:

+----------+----------------+----------+----------------------------+
| IE       | Section        | Status   | Comments                   |
+----------+----------------+----------+----------------------------+
| Call     | Section 8.6.20 | Required |                            |
| Number   |                |          |                            |
|          |                |          |                            |
| Dial     | Section 8.6.20 | Required | Indicates if number        |
| Plan     |                |          | exists, is a partial       |
| Status   |                |          | match, etc.                |
|          |                |          |                            |
| Dial     | Section 8.6.20 | Optional | Inclusion is strongly      |
| Plan     |                |          | suggested.  The default is |
| Refresh  |                |          | 10 minutes.                |
+----------+----------------+----------+----------------------------+

6.8.3. DIAL Request Message 📞

the DIAL message is for IAX peers that don't keep their own dialplan/extension routing 🛣️ Once an extension has been validated by one or more DPREQ/DPREP exchanges, the number MAY be dialed in a DIAL message, using the 'called number' IE to say which extension you're trying to reach. The remote peer then takes care of the rest of call setup, including ringing the extension and letting the local peer know when it's been answered. It follows the same requirements as the NEW command (Section 6.2.2) ✨

The table below shows the IEs this message uses:

+-----------+---------------+----------+----------------------------+
| IE        | Section       | Status   | Comments                   |
+-----------+---------------+----------+----------------------------+
| Called    | Section 8.6.1 | Required |                            |
| Number    |               |          |                            |
|           |               |          |                            |
| Called    | Section 8.6.5 | Optional | Use this IE if context is  |
| Context   |               |          | other than default.        |
+-----------+---------------+----------+----------------------------+

6.9. Miscellaneous 🧸

6.9.1. ACK: Acknowledgement Message 🫶

an ACK is how you say "got it" for an IAX message 🙌 It gets sent when a Full Frame comes in that doesn't have any other protocol-defined response. An ACK MUST have both a source call number and destination call number. It MUST also not change the sequence number counters, and MUST return the same time-stamp it received. That time-stamp is how the originating peer figures out which message the ACK is replying to 🕰️ Getting an ACK requires no action, so no drama there 😌

An ACK MAY also go out as the first acknowledgment of an IAX message that needs some other protocol-defined acknowledgment, as long as the required message also gets sent within some peer-defined amount of time. This lets the acknowledging peer hold off on sending the real IAX message, which can add security against brute-force password attacks during authentication exchanges 🔐 secure bestie behaviour

When any of these messages are received, an ACK MUST be sent in return: NEW, HANGUP, REJECT, ACCEPT, PONG, AUTHREP, REGREL, REGACK, REGREJ, TXREL. ACKs SHOULD not be expected by any peer, and their whole purpose is just to force the transport layer to be up to date 🆙 no cap, they're basically a nudge.

The ACK message does not requires any IEs. 🙈

6.9.2. INVAL: Invalid Response Message 🚫

an INVAL gets sent as a response to a message that isn't valid 🙅‍♀️ This happens when an IAX peer keeps sending messages on a call after the remote peer has already hung up its end. Upon receipt of an INVAL, a peer MUST destroy its side of a call. Literally done, bye 👋

The INVAL message does not requires any IEs. 💀

6.9.3. VNAK: Voice Negative Acknowledgement Message 🎙️

a VNAK goes out when messages show up out of order, especially when a Mini Frame lands before the first full voice frame on a call 😵‍💫 It's basically a request to resend dropped messages. A message counts as out of sequence if its received iseqno is different from the expected iseqno. On receipt of a VNAK, a peer MUST retransmit all frames with a higher sequence number than the VNAK message's iseqno. Retransmit energy, fr fr 🔁

The VNAK message does not requires any IEs. 🌸

6.9.4. MWI: Message Waiting Indicator Request Message 📬

an MWI message tells a remote peer that it has one or more messages waiting for it 💌 It MAY include the 'msgcount' IE to say how many messages are waiting.

The following table shows the IEs used by this message:

        +----------+----------------+----------+-----------+
        | IE       | Section        | Status   | Comments  |
        +----------+----------------+----------+-----------+
        | MSGCOUNT | Section 8.6.23 | Optional | Suggested |
        +----------+----------------+----------+-----------+

6.9.5. UNSUPPORT Unsupported Response Message 🙃

an UNSUPPORT message is sent back when a message isn't supported by an IAX peer 🤷‍♀️ This happens when an IAX command with an unrecognized or unsupported subclass comes in. No action is required when you get this message, though the peer SHOULD be aware that the message mentioned in the optionally included 'IAX unknown' IE isn't supported by the remote peer 🧐

The table below shows the IEs used by this message:

         +---------+----------------+----------+-----------+
         | IE      | Section        | Status   | Comments  |
         +---------+----------------+----------+-----------+
         | UNKNOWN | Section 8.6.22 | Optional | Suggested |
         +---------+----------------+----------+-----------+

6.10. Media Messages 🎧

the IAX protocol supports lots of media types, and they all travel through the same UDP port as the other IAX messages 🌈 Voice and video are the unique ones because they use two different encodings, and each one has its own support procedures. Abbreviated 'Mini Frames' are normally used for audio and video. However, each time the time-stamp is a multiple of 32,768 (0x8000 hex), a standard or 'Full Frame' MUST be sent ⭐ This is the clever part: it's efficient and reliable because most of the time you're sending compressed packets with no guaranteed delivery, and then every so often it forces a reliable exchange with the peer 🧠 If communication fails, call tear-down procedures get invoked 💔

Upon receiving any media message, except the abbreviated audio and video Mini Frames, an ACK message MUST be sent. The content SHOULD be passed to an associated application, device, or call leg, and the data MAY be buffered before it's presented to the user 🎀

6.10.1. DTMF Media Message ☎️

this message carries a single digit of DTMF (Dual Tone Multi-Frequency) 🔢 If you want some background info on DTMF, check out [RFC4733] and [RFC4734]. Just note that IAX does not use the RTP protocol, so it's its own thing 💅

6.10.2. Voice Media Message 🎤

this message carries voice data and tells you which CODEC was used 🎶

6.10.3. Video Media Message 🎬

this frame carries video data and tells you what video format the data is in 📺

6.10.4. Text Media Message 💬

this frame carries a text message in UTF-8 [RFC3629] format 🌷

6.10.5. Image Media Message 🖼️

this message carries a single image. The image MUST fit in one message in this version of the protocol. No splitting it up, it's all or nothing 🧚

6.10.6. HTML Media Message 🌐

the HTML message class carries HTML and related data, plus status about how that HTML page is displaying 🪄 The subclass parameter tells you which HTML content type it is. It MAY be a URL, or the start, middle, or end of a data block. HTML data MUST be in the format described in [html401] 🧾

If a peer gets an HTML message for a channel that doesn't support HTML, it MUST respond with an HTML message that has the HTML NOT SUPPORTED indication. Not it 🙅‍♀️

When a device that supports HTML finishes loading the page, it SHOULD send a LOAD COMPLETE message.

6.10.7. Comfort Noise Media Message 🌙

this message says comfort noise SHOULD be played 😴 It has a parameter that shows the level, and the noise is generated locally on the device, so no extra audio needed 🎧


7. Message Transport 🚚

IAX is sent over UDP and uses an application-level protocol to give you reliable transport where it's needed 💪

There are two message formats: reliable messages, which are the 'Full Frames', and unacknowledged 'Mini' or 'Meta' frames. All messages except certain voice and video messages are reliable 🫧 Reliable messages get moved along by a scheme that keeps message counts and time-stamps for both peers in the call. The counts are per call. Each peer keeps a timer for all reliable messages, and it MUST periodically retransmit those messages until they get acknowledged or the retry limit is exceeded ⏱️

When starting a call, the outgoing and incoming message sequence numbers MUST both be set to zero 🌟 Each reliable message that gets sent bumps the message count by one, except the ACK, INVAL, TXCNT, TXACC, and VNAK messages, which don't change the message count. The message includes the outgoing message count and the highest numbered incoming message that has been received. It also has a time-stamp showing how many milliseconds have passed since the call started. Or, for certain network timing messages, it has a copy of the time-stamp that was sent to it. Time-stamps MAY be approximate, but, MUST be in order 🕒

When any message is received, the time-stamps MUST be checked to make sure they're in order. If a message arrives out of order, it MUST be ignored and a VNAK message sent to resynchronize the peers 🔄 If the message is a reliable message, the incoming message counter MUST be used to acknowledge all the messages up to that sequence number that have been sent 🧾

If no acknowledgment is received after a locally configured number of retries (default 4), the call leg SHOULD be considered unusable, and the call MUST be torn down without any further interaction on this call leg 💀 that's the end of that leg, no more notes

7.1. Trunking ✨

okay so IAX lets multiple media exchanges between the same two peers get squished into ONE trunk call 🦋 which is so efficient bestie. Trunking MAY happen in one or both directions of an IAX exchange 💖 A trunk is made of a trunk header plus one or more trunked IAX calls 🎀 The trunk message carries a time-stamp for when the trunk frame was sent ⏰ and the audio data from the trunked calls gets wrapped up in the trunk frame right after the header 🌸 Each trunked call is literally three bits of info: two octets for the call's source number, two octets for how long the media data is in octets, and then the media data itself 🧚 IAX also lets you send along the time-stamps of each encapsulated Mini Frame, so jitter buffers and friends can have accurate timing info 🙈 There's a flag in the meta command header that says whether the encapsulated Mini Frames keep their original time-stamps. If they don't keep them, they MUST assume the time-stamp from the trunk header when the trunk peer receives them 🫶

7.2. Timers 💅

there are a bunch of timers in IAX 🕰️ there are also app-level timers like the call timer and ring timer, but those are out of scope for this doc, so we're not touching them 🙅‍♀️ this section covers the IAX timers and says what their default values and behaviors are 💜

7.2.1. Retransmission Timer

the message retransmission stuff is covered in Section 7 🔁 on every call there's a timer for how long to wait for an acknowledgment of a message ⏳ it starts at twice the measured Round-Trip Time from the last PING/PONG command 🏓 if a retransmission is needed, the timer grows exponentially until it hits a boundary value 📈 and the maximum retry time period boundary is 10 seconds 💀

7.2.2. Registration Period Timer

registrations are only valid for a specified time period 📅 it's the client's job to renew before that period runs out 🫶 registrations SHOULD be renewed at random intervals so the network doesn't get congested 🌈 and a registrar MUST keep an eye on this time period and invalidate the registration if the client/registrant hasn't renewed before the timer elapses 👑

7.3. NAT Considerations 🦋

IAX is super well suited to living behind NAT because it uses a single port 🎀 that means there are no start-of-call media stream delays while the NAT gateway sets up a bidirectional port association ✨ deploying a single IAX server behind a NAT gateway takes very little effort 💅 if the server is a registrar, the IAX UDP port on the NAT gateway must be forwarded to the server 🫠 if the server is a registrant (the default), the 60 second REGREQ refresh timer should be sufficient to keep the port association alive in the NAT gateway 🌸 still, a static port mapping is preferred 💖

if you're deploying multiple servers behind a single NAT gateway, most NAT gateways need each IAX server to use a different UDP port 🙈 that said, there might be NAT implementations that notice when multiple devices use the same private port and handle it properly 🧚

7.4. Encryption 🔐

IAX supports call encryption with the symmetric key Rijndael [AES] block cipher (aka AES, the Advanced Encryption Standard) 💜 Rijndael is a 128-bit block cipher that uses a shared secret 🗝️ IAX encrypts on a call-by-call basis, starting with a plaintext NEW message that says, along with the other message parameters, that the call should be encrypted 🙌 that indication comes from sending the ENCRYPTION IE (Section 8.6.34) in the NEW request message 🎀 if the called host supports encryption, it replies with a plaintext AUTHREQ message that also includes the ENCRYPTION IE ✨ every message after that in the call MUST be encrypted 🔒 if the called host doesn't support encryption, the AUTHREQ sent in response to the NEW must not include the ENCRYPTION IE, and the calling host MUST either HANGUP the request or continue with the unencrypted call 😭

the key for encrypting messages gets computed by taking the CHALLENGE IE (Section 8.6.14) from the AUTHREQ, concatenating it with any one of the shared passwords, and then computing the 128-bit MD5 digest of that combo 🧁 to decrypt, if there's more than one password for the peer, each one has to be tried until the message decodes successfully 🔓 the key stays the same for the whole call 💅 and only the data portion of the messages gets encoded 🌈

8. Message Encoding 📦

8.1. Frame Structure 🧩

this section has the spec for each type of frame that IAX defines 💖

8.1.1. Full Frames

Full Frames can carry signaling or media data 📞 generally they're used to control setting up, initiating, and terminating an IAX call, but they can also carry stream data (though that's usually not optimal 🙈)

Full Frames are sent reliably, so every Full Frame needs an immediate acknowledgment when it's received ✅ that ack can be explicit through an 'ACK' message (see Section 8.4) or implicit, based on getting an appropriate response to the Full Frame that was sent 🫶

the standard Full Frame header length is 12 octets 📏

Field descriptions:

'F' bit 🚩

This bit says whether or not the frame is a Full Frame. If the 'F' bit is set to 1, the frame is a Full Frame. If it's set to 0, it's not 🙌

Source call number 📤

This 15-bit value is the call number the transmitting client uses to identify this call. The source call number for an active call MUST NOT be in use by another call on the same client 🚫 call numbers MAY be reused once a call is no longer active, i.e., either when there's positive acknowledgment that the call has been destroyed or when all possible timeouts for the call have expired ⏳

'R' bit 🔁

This bit says whether or not the frame is being retransmitted. If the 'R' bit is set to 0, the frame is being sent for the first time. If it's set to 1, the frame is being retransmitted. IAX does not specify a retransmit timeout, so that's left up to the implementor 🛠️

Destination call number 📥

This 15-bit value is the call number the transmitting client uses to reference the call at the remote peer 🎯 it's the same as the remote peer's source call number 🪞 the destination call number uniquely identifies a call on the remote peer, and the source call number uniquely identifies the call on the local peer 💜

Time-stamp ⏰

The time-stamp field holds a 32-bit time-stamp maintained by an IAX peer for a given call 🕰️ it's an incrementally increasing count of the milliseconds since the first transmission of the call ✨

OSeqno 🔢

The 8-bit OSeqno field is the outbound stream sequence number. When a call is initialized, its value is 0 🐣 it goes up incrementally as Full Frames are sent. When the counter overflows, it silently resets to 0 🌀

ISeqno 🔢

The 8-bit ISeqno field is the inbound stream sequence number. When a call is initialized, its value is 0 🐣 it goes up incrementally as Full Frames are received. At any time, the ISeqno of a call is the next expected inbound stream sequence number 👀 when the counter overflows, it silently resets to 0 🌀

Frametype 🏷️

The Frametype field identifies the type of message carried by the frame. See Section 8.2 for more info 💅

'C' bit 🧠

This bit determines how the remaining 7 bits of the Subclass field are coded. If the 'C' bit is set to 1, the Subclass value is read as a power of 2 🧮 if it's not set, the Subclass value is read as a simple 7-bit unsigned integer 🔢

                    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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|     Source Call Number      |R|   Destination Call Number   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            time-stamp                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    OSeqno     |    ISeqno     |   Frame Type  |C|  Subclass   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
:                             Data                              :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 5: Full Frame Binary Format 💜

8.1.2. Mini Frames ✨

Okay so Mini Frames get their name because their header is a tiny 4 octets 🤏 They carry no control or signaling data at all. Their one job is to carry a media stream on an IAX call that's already set up 📞 They are sent unreliably, and honestly that makes sense. VoIP calls can usually miss several frames without the call getting noticeably worse, but making sure everything arrives adds overhead, which eats bandwidth and lowers throughput. Plus voice is real time, so by the time a lost frame could be resent, it's already too old to fit back into the audio 💀

Field descriptions:

  • 'F' bit: Mini Frames MUST have the 'F' bit set to 0 to say they are not Full Frames 🚫
  • Source call number: This is the number the transmitting peer uses to identify the current call 📇
  • time-stamp: Mini frames carry a 16-bit time-stamp, which is the lower 16 bits of the transmitting peer's full 32-bit time-stamp for the call ⏰ The time-stamp lets incoming frames get synchronized so they MAY be processed in chronological order, instead of the (possibly different) order they arrived in 🕰️ The 16-bit time-stamp wraps after 65.536 seconds, and at that point a full frame SHOULD be sent to tell the remote peer its time-stamp has been reset 🔄 A call MUST continue to send mini frames starting with time-stamp 0, even if the acknowledgment of the resynchronization never comes back 🫶

The F bit, source call number, and 16-bit time-stamp together make up the entire 4-octet header. The spec says "for a full frame" right here, so I'm just reporting it as written 👀 Following this header is the actual stream data, of arbitrary length, up to whatever the maximum the network supports 🎶

Mini frames are implicitly defined to be of type 'voice frame' (frametype 2; see Section 8.2). The subclass is implicitly defined by the most recent full voice frame of a call, so the subclass for a voice frame is what specifies the CODEC used with the stream 🎧 The first voice frame of a call SHOULD be sent using the CODEC agreed upon in the initial CODEC negotiation ✨ On-the-fly CODEC negotiation is permitted by sending a full voice frame that specifies the new CODEC to use in the subclass field 💅

                    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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|     Source call number      |            time-stamp         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
:                             Data                              :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 6: Mini Frame Binary Format 🦋


8.1.3. Meta Frames 🌸

Meta frames serve one of two purposes, and both are about saving bytes 🍓 Meta video frames let video streams go out with an optimized header, kind of like how mini voice frames work. Meta trunk frames are used for trunking multiple IAX media streams between two peers into one header, so bandwidth usage gets trimmed even further 📉

8.1.3.1. Meta Video Frames 🎬

Field descriptions:

  • 'F' bit: Meta video frames MUST have the 'F' bit set to 0 to indicate that they are not full frames 🙅‍♀️
  • Meta Indicator: This is a 15-bit field of all zeroes, used to show that the frame is a Meta Frame 🔍 Meta Frames are easy to spot because the first 16 bits are always zero in any Meta Frame. Full or Mini Frames will have either the 'F' bit set or some nonzero value for the source call number (or both) 👑
  • 'V' bit: The 'V' bit in a meta video frame is set to 1 to specify that the frame is a meta video frame 📹
  • Source call number: This is the call number the transmitting peer uses to identify this video call 🔢
  • time-stamp: Meta video frames carry a 16-bit time-stamp, which is the lower 16 bits of the transmitting peer's full 32-bit time-stamp for the call ⏱️ When this time-stamp wraps, a Full Frame SHOULD be sent to tell the remote peer that the time-stamp has been reset to 0 🔁

Following the time-stamp is the actual video stream data 🎥 Meta video frames are implicitly defined to be of type 'video frame' (frametype 3; see Section 8.2). The video CODEC used is implicitly defined by the subclass of the most recent full video frame of a call 🌈

                    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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|         Meta Indicator      |V|      Source Call Number     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|?|          time-stamp         |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
|                                         Data                  |
:                                                               :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 7: Meta Video Frame Binary Format 💜

8.1.3.2. Meta Trunk Frames ✨

okay so IAX has two ways to squish a bunch of media streams between the same two peers into one association 🫧 the first way sends a regular meta header plus a single 32-bit time-stamp for when the trunk frame was sent. after that comes one or more media frames, each with its call number and the length in octets of its stream data 💖

the second way is basically the first, but with a twist 💅 it also sends the 32-bit time-stamp for the trunk frame, but the media frames inside are full-on Mini Frames, each with its own 16-bit time-stamp for its call 🦋 the first method is a teeny bit more efficient (2 fewer octets per call in the trunk), but the second method keeps each call's own time-stamp, so the jitter buffer can use the accurate call time-stamp instead of the less precise one for the whole trunk 🎀 either method is totally allowed 🌸

Field descriptions:

'F' bit 🚩

Meta trunk frames MUST have the 'F' bit set to 0 so everyone knows they aren't Full Frames 🙅‍♀️

Meta Indicator 🧩

This is a 15-bit field of all zeroes that says "hey, I'm a Meta Frame" 🧚 you can spot Meta Frames because their first 16 bits are always zero. Full Frames and Mini Frames always have either the 'F' bit set or a nonzero source call number (or both) 👑

'V' bit 🎬

In a meta trunk frame, the 'V' bit is set to 0 to say it's not a meta video frame 💜

Meta Command 🍓

This 7-bit field tells you if the Meta Frame is a trunk. A value of '1' means it's a meta trunk frame 🔥 everything else is reserved for future use, and you can check the IANA Registry for the other IAX Meta Command Assignments 📚

Command Data 🌈

This 8-bit field holds flags for options that apply to a trunked call. The least significant bit is the 'trunk time-stamps' flag. A value of 0 means the calls in the trunk don't have their own time-stamps, and a value of 1 means each call does 🫶 all the other bits are reserved for later 💀

time-stamp ⏰

Meta trunk frames carry a 32-bit time-stamp showing the actual moment the trunk frame was sent. This is totally separate from the time-stamps of the calls inside the trunk ✨

After the 32-bit time-stamp come one or more trunked calls 🎀 If the 'trunk time-stamps' flag is set to 0, each entry is 2 octets of source call number, 2 octets of media data length, and then the media data itself. If the 'trunk time-stamps' flag is set to 1, each entry is 2 octets of media data length, and then a Mini Frame (2 octets of source call number, 2 octets of 16-bit time-stamp, and the media data) 🧁 the two diagrams below help you picture it 👀

                    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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|         Meta Indicator      |V|Meta Command | Cmd Data (0)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            time-stamp                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R|      Source Call Number     |     Data Length (in octets)   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
:                             Data                              :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                               .
                               .
                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R|      Source Call Number     |     Data Length (in octets)   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
:                             Data                              :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 8: Meta Trunk Frame Binary Format (trunk time-stamps 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|         Meta Indicator      |V|Meta Command | Cmd Data (1)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            time-stamp                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Data Length (in octets)   |R|     Source Call Number      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           time-stamp          |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
|                                       Data                    |
:                                                               :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                               .
                               .
                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Data Length (in octets)   |R|     Source Call Number      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           time-stamp          |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
|                                       Data                    |
:                                                               :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 9: Meta Trunk Frame Binary Format (trunk time-stamps 1)

8.1.4. Encrypted Frames 🔐

all of the above frames may be encrypted 🤫 the header call numbers stay in the clear (the first 4 bytes for a Full Frame, or 2 bytes for a Mini Frame). then the rest of the frame gets padded with between 16 and 32 bytes of random data and encrypted with AES, with each block XOR'd with the block before it 🌸 the padding goes at the front of the data 🎀

Figure 10 shows a padded Full Frame before encryption, and Figure 11 shows it after. other frame types do the exact same thing, except their cleartext part is shorter, like we said above 💖

                    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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|     Source Call Number      |R|   Destination Call Number   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         12 Random bytes                       |
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               28  Random bits                         |padding|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
: between 0 and 15 (as indicated by the padding field above)    :
:                         Random bytes                          :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
:                    Remainder of Actual Frame                  :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 10: Full Frame before encryption

AES needs a 16 byte block size, so padding is a must 🧸 it lives at the start of the payload because that makes it harder to exploit how predictable the IAX frame header is 🕵️‍♀️ for example, the first encrypted Frame an IAX client sends within an incoming IAX call is totally predictable 😭 it's always an ACK, and even the time-stamp is guessable, since it's the time the AUTHREP packet was sent 💀

                    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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|     Source Call Number      |R|   Destination Call Number   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Encrypted data                        |
|                Multiple of 16 bytes                           |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 11: Frame after encryption

the same encryption rules apply to Mini Frames, except the unencrypted front part is only 2 bytes 🦋


8.2. Frame Types 🎀

the IAX protocol specifies 10 types of possible frames for the "frametype" field of a Full Frame 👑 they're each described in the subsections below 💅

8.2.1. DTMF Frame ☎️

this frame carries a single digit of DTMF (Dual Tone Multi-Frequency) 📞 you can find more info about DTMF in RFC 4733 [RFC4733] and [RFC4734] 📚

for DTMF frames, the subclass is the actual DTMF digit the frame is carrying 🔢

8.2.2. Voice Frame 🎤

this frame carries voice data 🫶

the subclass specifies the audio format of the data 🎧 you can find the predefined voice formats in Section 8.7 ✨

8.2.3. Video Frame 🎥

this frame carries video data 🎬

the subclass specifies the video format of the data 📼 you can find the predefined video formats in Section 8.7 💜

8.2.4. Control Frame 🕹️

this frame carries session control data, which means it's about controlling a device connected to an IAX endpoint 🎛️

the subclass is a value from Section 8.3 that describes the device control signal 🧃

8.2.5. Null Frame 🫥

Frames with the Null value MUST NOT be transmitted 🙅‍♀️ bestie, that's a hard no 💀

8.2.6. IAX Frame 🧚

this frame carries control data for IAX protocol-specific endpoint management 🌈 it's used to manage IAX protocol interactions that are mostly independent of the type of endpoints involved 🍓

the subclass is a value from Section 8.4 that describes an IAX event 📅

8.2.7. Text Frame 💬

this frame carries a non-control text message in UTF-8 [RFC3629] format 🌸

all text frames have a subclass of 0 🫶

8.2.8. Image Frame 🖼️

this frame carries a single image 📸

the subclass describes the format of the image, and you can find those formats in Section 8.7 🦋

8.2.9. HTML Frame 🌐

this frame carries HTML data 💻

the subclass is a value from the HTML Subclasses table in Section 8.5 🍓

8.2.10. Comfort Noise Frame 🌙

okay so the Comfort Noise Frame is all about carrying comfort noise 🫶 ✨ The subclass is the level of that comfort noise, measured in -dBov 🎀

+------+-------------+--------------------------+-------------------+
| TYPE | Description | Subclass Description     | Data Description  |
+------+-------------+--------------------------+-------------------+
| 0x01 | DTMF        | 0-9, A-D, *, #           | Undefined         |
|      |             |                          |                   |
| 0x02 | Voice       | Audio Compression Format | Data              |
|      |             |                          |                   |
| 0x03 | Video       | Video Compression Format | Data              |
|      |             |                          |                   |
| 0x04 | Control     | See Control Frame Types  | Varies with       |
|      |             |                          | subclass          |
|      |             |                          |                   |
| 0x05 | Null        | Undefined                | Undefined         |
|      |             |                          |                   |
| 0x06 | IAX Control | See IAX Protocol         | Information       |
|      |             | Messages                 | Elements          |
|      |             |                          |                   |
| 0x07 | Text        | Always 0                 | Raw Text          |
|      |             |                          |                   |
| 0x08 | Image       | Image Compression Format | Raw image         |
|      |             |                          |                   |
| 0x09 | HTML        | See HTML Frame Types     | Message Specific  |
|      |             |                          |                   |
| 0x0A | Comfort     | Level in -dBov of        | None              |
|      | Noise       | comfort noise            |                   |
+------+-------------+--------------------------+-------------------+

the table above is the full list of valid Frame Type Values, so bookmark it bestie 💅 Also, for extra IAX Frame Type values, go check the IANA Registry 🌸

8.3. Control Frames Subclasses 💖

here's the table of every valid Control Frame Subclass, and yes it's giving organized 📋

+-------------+---------------+-------------------------------------+
| VALUE       | Name          | Description                         |
+-------------+---------------+-------------------------------------+
| 0x01        | Hangup        | The call has been hungup at the     |
|             |               | remote end                          |
|             |               |                                     |
| 0x02        | Reserved      | Reserved for future use             |
|             |               |                                     |
| 0x03        | Ringing       | Remote end is ringing (ring-back)   |
|             |               |                                     |
| 0x04        | Answer        | Remote end has answered             |
|             |               |                                     |
| 0x05        | Busy          | Remote end is busy                  |
|             |               |                                     |
| 0x06        | Reserved      | Reserved for future use             |
|             |               |                                     |
| 0x07        | Reserved      | Reserved for future use             |
|             |               |                                     |
| 0x08        | Congestion    | The call is congested               |
|             |               |                                     |
| 0x09        | Flash Hook    | Flash hook                          |
|             |               |                                     |
| 0x0a        | Reserved      | Reserved for future use             |
|             |               |                                     |
| 0x0b        | Option        | Device-specific options are being   |
|             |               | transmitted                         |
|             |               |                                     |
| 0x0c        | Key Radio     | Key Radio                           |
|             |               |                                     |
| 0x0d        | Unkey Radio   | Unkey Radio                         |
|             |               |                                     |
| 0x0e        | Call Progress | Call is in progress                 |
|             |               |                                     |
| 0x0f        | Call          | Call is proceeding                  |
|             | Proceeding    |                                     |
|             |               |                                     |
| 0x10        | Hold          | Call is placed on hold              |
|             |               |                                     |
| 0x11        | Unhold        | Call is taken off hold              |
+-------------+---------------+-------------------------------------+

ngl the Reserved entries are just placeholders for later, so don't try to use them rn 🙈 And for more IAX Control Frame Subclass values, check the IANA Registry 🦋

8.4. IAX Frames 🧚

okay so IAX Frames are the ones that handle management of IAX endpoints 💜 They take care of IAX signaling (like call setup, maintenance, and tear-down) 📞 They MAY also handle direct transmission of media data, but that's not optimal for VoIP calls, lowkey not the move 🙅‍♀️ They don't carry session-specific control (like device state), because that's literally what Control Frames are for 🎀 The IAX commands are listed right below ✨

here's every valid IAX Frame value, the full menu 🍓

+------+-----------+-----------------------------------------+
| Hex  | Name      | Description                             |
+------+-----------+-----------------------------------------+
| 0x01 | NEW       | Initiate a new call                     |
|      |           |                                         |
| 0x02 | PING      | Ping request                            |
|      |           |                                         |
| 0x03 | PONG      | Ping or poke reply                      |
|      |           |                                         |
| 0x04 | ACK       | Explicit acknowledgment                 |
|      |           |                                         |
| 0x05 | HANGUP    | Initiate call tear-down                 |
|      |           |                                         |
| 0x06 | REJECT    | Reject a call                           |
|      |           |                                         |
| 0x07 | ACCEPT    | Accept a call                           |
|      |           |                                         |
| 0x08 | AUTHREQ   | Authentication request                  |
|      |           |                                         |
| 0x09 | AUTHREP   | Authentication reply                    |
|      |           |                                         |
| 0x0a | INVAL     | Invalid message                         |
|      |           |                                         |
| 0x0b | LAGRQ     | Lag request                             |
|      |           |                                         |
| 0x0c | LAGRP     | Lag reply                               |
|      |           |                                         |
| 0x0d | REGREQ    | Registration request                    |
|      |           |                                         |
| 0x0e | REGAUTH   | Registration authentication             |
|      |           |                                         |
| 0x0f | REGACK    | Registration acknowledgement            |
|      |           |                                         |
| 0x10 | REGREJ    | Registration reject                     |
|      |           |                                         |
| 0x11 | REGREL    | Registration release                    |
|      |           |                                         |
| 0x12 | VNAK      | Video/Voice retransmit request          |
|      |           |                                         |
| 0x13 | DPREQ     | Dialplan request                        |
|      |           |                                         |
| 0x14 | DPREP     | Dialplan reply                          |
|      |           |                                         |
| 0x15 | DIAL      | Dial                                    |
|      |           |                                         |
| 0x16 | TXREQ     | Transfer request                        |
|      |           |                                         |
| 0x17 | TXCNT     | Transfer connect                        |
|      |           |                                         |
| 0x18 | TXACC     | Transfer accept                         |
|      |           |                                         |
| 0x19 | TXREADY   | Transfer ready                          |
|      |           |                                         |
| 0x1a | TXREL     | Transfer release                        |
|      |           |                                         |
| 0x1b | TXREJ     | Transfer reject                         |
|      |           |                                         |
| 0x1c | QUELCH    | Halt audio/video [media] transmission   |
|      |           |                                         |
| 0x1d | UNQUELCH  | Resume audio/video [media] transmission |
|      |           |                                         |
| 0x1e | POKE      | Poke request                            |
|      |           |                                         |
| 0x1f | Reserved  | Reserved for future use                 |
|      |           |                                         |
| 0x20 | MWI       | Message waiting indication              |
|      |           |                                         |
| 0x21 | UNSUPPORT | Unsupported message                     |
|      |           |                                         |
| 0x22 | TRANSFER  | Remote transfer request                 |
|      |           |                                         |
| 0x23 | Reserved  | Reserved for future use                 |
|      |           |                                         |
| 0x24 | Reserved  | Reserved for future use                 |
|      |           |                                         |
| 0x25 | Reserved  | Reserved for future use                 |
+------+-----------+-----------------------------------------+

and yep, for additional IAX Frame values, go check the IANA Registry 🌈

8.5. HTML Command Subclasses

okay so these are the little sub-commands that live inside an HTML frame, and the whole lineup is giving 💅🌸

                  +--------+----------------------------+
                  | NUMBER | DESCRIPTION                |
                  +--------+----------------------------+
                  | 0x01   | Sending a URL              |
                  |        |                            |
                  | 0x02   | Data frame                 |
                  |        |                            |
                  | 0x04   | Beginning frame            |
                  |        |                            |
                  | 0x08   | End frame                  |
                  |        |                            |
                  | 0x10   | Load is complete           |
                  |        |                            |
                  | 0x11   | Peer does not support HTML |
                  |        |                            |
                  | 0x12   | Link URL                   |
                  |        |                            |
                  | 0x13   | Unlink URL                 |
                  |        |                            |
                  | 0x14   | Reject Link URL            |
                  +--------+----------------------------+

Want the rest? Check the IANA Registry for more IAX HTML Command Subclass values 🧚

8.6. Information Elements

IAX messages that go out as Full Frames MAY carry information elements 🎀, which are little bundles of user- or call-specific data tucked into the frame's data field. Zero, one, or multiple information elements MAY be included with any IAX message, so you do you 💖

Here's how information elements are coded:

  • The first octet of any information element is the "IE" field 🌈. That's the identification number that defines which element you're looking at. Table 1 lists every defined information element, and each one gets its own explanation below the table.
  • The second octet is the "data length" field, which says how many octets the element's data field is.
  • The remaining octet(s) hold the actual data. How that data is represented depends on which element it is, as identified by its "IE" field. Some elements carry binary data, some carry UTF-8 [RFC3629] data, and some have no data field at all. Elements that carry UTF-8 MUST prepare strings as per [RFC3454] and [RFC3491], so illegal characters, case folding, and other character properties get handled and compared properly 🧼 Each element's data representation is described below.

The Information Element Binary Format looks like this:

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      IE       |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :             DATA              :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here's the full lineup of information elements IAX defines 👑 Each one has a quick description, and you'll get more detail on each IE below the table.

   +------+----------------+-------------------------------------------+
   | HEX  | NAME           | DESCRIPTION                               |
   +------+----------------+-------------------------------------------+
   | HEX  | NAME           | DESCRIPTION                               |
   | 0x01 | CALLED NUMBER  | Number/extension being called             |
   | 0x02 | CALLING NUMBER | Calling number                            |
   | 0x03 | CALLING ANI    | Calling number ANI for billing            |
   | 0x04 | CALLING NAME   | Name of caller                            |
   | 0x05 | CALLED CONTEXT | Context for number                        |
   | 0x06 | USERNAME       | Username (peer or user) for               |
   |      |                | authentication                            |
   | 0x07 | PASSWORD       | Password for authentication               |
   | 0x08 | CAPABILITY     | Actual CODEC capability                   |
   | 0x09 | FORMAT         | Desired CODEC format                      |
   | 0x0a | LANGUAGE       | Desired language                          |
   | 0x0b | VERSION        | Protocol version                          |
   | 0x0c | ADSICPE        | CPE ADSI capability                       |
   | 0x0d | DNID           | Originally dialed DNID                    |
   | 0x0e | AUTHMETHODS    | Authentication method(s)                  |
   | 0x0f | CHALLENGE      | Challenge data for MD5/RSA                |
   | 0x10 | MD5 RESULT     | MD5 challenge result                      |
   | 0x11 | RSA RESULT     | RSA challenge result                      |
   | 0x12 | APPARENT ADDR  | Apparent address of peer                  |
   | 0x13 | REFRESH        | When to refresh registration              |
   | 0x14 | DPSTATUS       | Dialplan status                           |
   | 0x15 | CALLNO         | Call number of peer                       |
   | 0x16 | CAUSE          | Cause                                     |
   | 0x17 | IAX UNKNOWN    | Unknown IAX command                       |
   | 0x18 | MSGCOUNT       | How many messages waiting                 |
   | 0x19 | AUTOANSWER     | Request auto-answering                    |
   | 0x1a | MUSICONHOLD    | Request musiconhold with QUELCH           |
   | 0x1b | TRANSFERID     | Transfer Request Identifier               |
   | 0x1c | RDNIS          | Referring DNIS                            |
   | 0x1d | Reserved       | Reserved for future use                   |
   | 0x1e | Reserved       | Reserved for future use                   |
   | 0x1f | DATETIME       | Date/Time                                 |
   | 0x20 | Reserved       | Reserved for future use                   |
   | 0x21 | Reserved       | Reserved for future use                   |
   | 0x22 | Reserved       | Reserved for future use                   |
   | 0x23 | Reserved       | Reserved for future use                   |
   | 0x24 | Reserved       | Reserved for future use                   |
   | 0x25 | Reserved       | Reserved for future use                   |
   | 0x26 | CALLINGPRES    | Calling presentation                      |
   | 0x27 | CALLINGTON     | Calling type of number                    |
   | 0x28 | CALLINGTNS     | Calling transit network select            |
   | 0x29 | SAMPLINGRATE   | Supported sampling rates                  |
   | 0x2a | CAUSECODE      | Hangup cause                              |
   | 0x2b | ENCRYPTION     | Encryption format                         |
   | 0x2c | ENCKEY         | Reserved for future Use                   |
   | 0x2d | CODEC PREFS    | CODEC Negotiation                         |
   | 0x2e | RR JITTER      | Received jitter, as in RFC 3550           |
   | 0x2f | RR LOSS        | Received loss, as in RFC 3550             |
   | 0x30 | RR PKTS        | Received frames                           |
   | 0x31 | RR DELAY       | Max playout delay for received frames in  |
   |      |                | ms                                        |
   | 0x32 | RR DROPPED     | Dropped frames (presumably by jitter      |
   |      |                | buffer)                                   |
   | 0x33 | RR OOO         | Frames received Out of Order              |
   | 0x34 | OSPTOKEN       | OSP Token Block                           |
   +------+----------------+-------------------------------------------+

Table 1: Information Element Definitions

Want more IE values? The IANA Registry has them 🦋

8.6.1. CALLED NUMBER ✨

The CALLED NUMBER information element tells everyone which number or extension is being called 📞 It carries UTF-8-encoded data. It MUST use UTF-8 encoding and not numeric data, because destinations aren't limited to E.164 numbers ([E164]), national numbers, or even digits. A number or extension can totally include non-numeric characters 💅 The CALLED NUMBER IE MAY contain a SIP URI, [RFC3261], or a URI in any other format. Whether a server can serve a CALLED NUMBER depends on the server.

The CALLED NUMBER information element is generally sent with IAX NEW, DPREQ, DPREP, DIAL, and TRANSFER messages.

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x01     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :  UTF-8-encoded CALLED NUMBER  :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.2. CALLING NUMBER 📱

The CALLING NUMBER information element says which number or extension the calling entity is, for the remote peer 💖 It carries UTF-8-encoded data.

The CALLING NUMBER information element is usually sent with IAX NEW messages.

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x02     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   : UTF-8-encoded CALLING NUMBER  :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.3. CALLING ANI 🧾

The CALLING ANI information element is the calling number's ANI (Automatic Number Identification), used for billing 💰 It carries UTF-8-encoded data.

The CALLING ANI information element MAY be sent with an IAX NEW message, but it is not required.

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x03     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :   UTF-8-encoded CALLING ANI   :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.4. CALLING NAME 🫶

The CALLING NAME information element carries the calling name of the transmitting peer 🌷 It carries UTF-8-encoded data.

The CALLING NAME information element is usually sent with IAX NEW messages.

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x04     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :   UTF-8-encoded CALLING NAME  :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.5. CALLED CONTEXT 🗺️

The CALLED CONTEXT information element tells the remote peer which context (or partition) of its dialplan the CALLED NUMBER gets interpreted in 🧠 It carries UTF-8-encoded data.

The CALLED CONTEXT information element MAY be sent with IAX NEW or TRANSFER messages, though it is not required.

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x05     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   : UTF-8-encoded CALLED CONTEXT  :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.6. USERNAME ✨

okay so the USERNAME information element is how you tell the other side who the user is in an IAX exchange 🫶 it carries UTF-8-encoded data, so names with emoji and accents are fine 💅

The USERNAME information element MAY be sent with IAX NEW, AUTHREQ, REGREQ, REGAUTH, or REGACK messages, or any time a peer needs to identify a user. 🦋

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x06     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :     UTF-8-encoded USERNAME    :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.7. CAPABILITY 🎀

the CAPABILITY information element tells everyone which media CODECs an IAX peer can handle 🎶 its data is a 4-octet bitmask, and you can see how the bits map in Section 8.7. you can OR several CODECs together into one CAPABILITY element if you want to show off, and multiple CODECs MAY be specified that way 👑

CAPABILITY gets sent with IAX NEW messages, but only if it fits the CODEC negotiation method the peer is using 🌸

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x08     |      0x04     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | CAPABILITY according to Media |
   | Format Subclass Values Table  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.8. FORMAT 💖

FORMAT is the one-and-only preferred CODEC element 💅 when it rides along with a NEW message, it's the CODEC the caller would love to use for the call. when it shows up in an ACCEPT message, it's the CODEC that actually got picked 🫶 its data is a 4-octet bitmask (see Section 8.7 for the bit layout), and only one CODEC MUST be specified in the FORMAT information element. no sneaking in two, bestie 🙈

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x09     |      0x04     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   FORMAT according to Media   |
   | Format Subclass Values Table  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.9. LANGUAGE 🌈

LANGUAGE is how the sending peer says which language it'd like the remote peer to use for signaling info 🌍 it carries UTF-8-encoded data, and the tags should be selected per [RFC5646] and [RFC4647] 🧚

The LANGUAGE information element MAY be sent with an IAX NEW message. ✨

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x0a     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :     UTF-8-encoded LANGUAGE    :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.10. VERSION 👑

VERSION tells everyone which protocol version the peer is running 🎀 both ends of a call MUST use the same protocol version, no mixing and matching 🙅‍♀️ right now the only supported version is 2, and the data field is 2 octets long 💜

The VERSION information element MUST be sent with an IAX NEW message. 💅

When VERSION gets sent, it MUST be the first IE in the message. it has to lead the pack 🦋

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x0b     |      0x02     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |            0x0002             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.11. ADSICPE 📞

ADSICPE says what the CPE (Customer Premises Equipment) ADSI (Analog Display Services Interface) capability is 🍓 its data field is 2 octets long.

The ADSICPE information element MAY be sent with an IAX NEW message. 🌸

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x0c     |      0x02     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |       ADSICPE Capability      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.12. DNID 🔥

DNID is the Dialed Number ID, and it can be different from the 'called number' 👀 it carries UTF-8-encoded data.

The DNID information element MAY be sent with an IAX NEW message. ✨

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x0d     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :    UTF-8-encoded DNID Data    :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.13. AUTHMETHODS 🔐

AUTHMETHODS is how a peer shows which authentication methods it accepts 💅 it's a bitmask that's two octets long, and the table below lists the valid methods 🧚

The AUTHMETHODS information element MUST be sent with IAX AUTHREQ and REGAUTH messages. 🫶

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x0e     |      0x02     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Valid Authentication Methods |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here are the valid values for authentication:

                   +--------+--------------------------+
                   | METHOD | DESCRIPTION              |
                   +--------+--------------------------+
                   | 0x0001 | Reserved (was Plaintext) |
                   |        |                          |
                   | 0x0002 | MD5                      |
                   |        |                          |
                   | 0x0004 | RSA                      |
                   +--------+--------------------------+

Refer to the IANA Registry for additional IAX Authentication Method values. 📚

8.6.14. CHALLENGE 🌙

CHALLENGE carries the MD5 or RSA challenge that gets offered for authentication 🎯 it holds the actual UTF-8-encoded challenge data.

The CHALLENGE information element MUST be sent with IAX AUTHREQ and REGAUTH messages. 💜

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x0f     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :  UTF-8-encoded Challenge Data :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.15. MD5 RESULT 🍓

MD5 RESULT is the MD5 response to an authentication CHALLENGE 🫶 it carries the UTF-8-encoded challenge result. the MD5 Result value is made by taking the MD5 [RFC1321] digest of the challenge string and the password string 🔐

The MD5 RESULT information element MAY be sent with IAX AUTHREP and REGREQ messages, but only if an AUTHREQ or REGAUTH and an appropriate CHALLENGE have been received. 🌸 MD5 RESULT MUST NOT be sent except in response to a CHALLENGE. no freelancing, bestie 🙅‍♀️

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     0x10      |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :    UTF-8-encoded MD5 Result   :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.16. RSA RESULT 🦋

RSA RESULT is the RSA response to an authentication CHALLENGE 💖 it carries the UTF-8-encoded challenge result. to make it, first you compute the SHA1 digest [RFC3174] of the challenge string, and then you RSA sign that SHA1 digest using the private RSA key as specified in PKCS #1 v2.0 [PKCS] 🔑 the RSA keys are stored locally, so they never leave your device 🏠

When an RSA RESULT information element comes in, its value must be verified with the sender's public key to match the SHA1 digest [RFC3174] of the challenge string. that's the check, periodt 💅

The RSA RESULT information element MAY be sent with IAX AUTHREP and REGREQ messages, but only if an AUTHREQ or REGAUTH and an appropriate CHALLENGE have been received. ✨ RSA RESULT MUST NOT be sent except in response to a CHALLENGE. 🙈

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x11     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :    UTF-8-encoded RSA Result   :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.17. APPARENT ADDR ✨

okay so the APPARENT ADDR IE is basically the "this is what I look like from the outside" info 💅 It tells a peer the network connection details it's perceived to have, which can be different from its real address when it's hiding behind NAT 🎀 The IE is filled in using the source address values from the UDP and IP headers of the IAX message this response is replying to. Its data field is the same POSIX sockaddr struct for whatever address family is in use (so sockaddr_in for IPv4, sockaddr_in6 for IPv6) and the data length depends on which kind of address you're representing 🦋

The APPARENT ADDR information element MUST be sent with IAX TXREQ and REGACK messages. With a TXREQ, the APPARENT ADDR MUST specify the address of the peer the local peer is trying to transfer its end of the connection to. With a REGACK, the APPARENT ADDR MUST specify the address it uses to reach the peer, which can be different from the address the peer thinks it has 🌸 (that happens with NAT or multi-homed peer machines, so don't be shocked when it doesn't match 🙈)

The data field is the same as the Linux struct sockaddr_in: two octets for the address family, two octets for the port number, four octets for the IPv4 address, and 8 octets of padding that are all bits set to 0. So the whole APPARENT ADDR IE comes out to 18 octets total 🧚

Here's the generic APPARENT ADDR format:

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x12     |  Data Length  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        sockaddr struct        |
:   for address family in use   :
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

And here's the APPARENT ADDR format for an IPv4 address:

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x12     |      0x10     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            0x0200             | <- Address family (INET)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            0x11d9             | <- Portno (default 4569)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      32-bit IP address        |
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |
|      8 octets of all 0s       |
|   (padding in sockaddr_in)    |
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

And here's the APPARENT ADDR format for an IPv6 address:

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x12     |      0x1C     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            0x0A00             | <- Address family (INET6)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            0x11d9             | <- Portno (default 4569)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           32 bits             | <- Flow information
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      128-bit IP address       | <- Ip6 Address
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           32 bits             | <- Scope ID
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.18. REFRESH 🔄

the REFRESH IE is all about timing ⏰ It tells you how many seconds are left before something expires, and its data field is 2 octets long.

It shows up in IAX REGREQ, REGACK, and DPREP messages. When it rides along with a REGREQ, it's a request: it asks the peer that's maintaining the registration to set its timeout to REFRESH seconds. When it's sent with a DPREP or REGACK, it's just informational, telling the remote peer when the local peer will stop treating the event as valid. And with a DPREP, the REFRESH tells a peer how long it SHOULD store the dialplan response it got 💜

If there's no REFRESH IE in a DPREP, the cache data is assumed to expire after 10 minutes. If there's no REFRESH IE in a REGACK, registration is assumed to expire after 60 seconds ⭐

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x13     |      0x02     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  2 octets specifying refresh  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.19. DPSTATUS 🎯

the DPSTATUS IE tells you the status of a CALLED NUMBER in a remote dialplan 👀 Its data field is a 2-octet bitmask made of flags (listed in the table below). Exactly one of the low 3 bits MUST be set, and zero, one, or two of the high 2 bits MAY be set. Like, be precise about it, bestie 🫶

The DPSTATUS IE MUST be sent with IAX DPREP messages, since it's the payload of the dialplan response 🍓

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x14     |      0x02     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|M|R|                     |N|C|E|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here's the table of dialplan status flags:

             +--------+------------------------------+
             | FLAG   | DESCRIPTION                  |
             +--------+------------------------------+
             | 0x0001 | Exists                       |
             |        |                              |
             | 0x0002 | Can exist                    |
             |        |                              |
             | 0x0004 | Non-existent                 |
             |        |                              |
             | 0x4000 | Retain dialtone (ignorepat)  |
             |        |                              |
             | 0x8000 | More digits may match number |
             +--------+------------------------------+

For more IAX dialplan status values, check the IANA Registry 📋

8.6.20. CALLNO 📞

the CALLNO IE is for transfers 🔀 It tells a remote peer which call number to use as the destination when it needs to identify a call that's being transferred. The peer managing the transfer sends the CALLNO for one transfer endpoint to the other transfer endpoint, so that endpoint knows what call number to put in for the transfer. Its data field is 2 octets, and the call number is specified the same way a source or destination call number is in a frame header ✨

The CALLNO IE MUST be sent with IAX TXREQ, TXREADY, and TXREL messages. Without it in the right transfer messages, the transfer cannot succeed 💀

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     0x15      |      0x02     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Callno of transfer recipient |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.21. CAUSE 🚨

the CAUSE IE explains why something happened 🤔 It carries a description of the cause of the event as UTF-8-encoded data. The event itself gets announced at the message level, so the CAUSE is just the reason behind it.

The CAUSE IE SHOULD be sent with IAX HANGUP, REJECT, REGREJ, and TXREJ messages 🫶

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x16     |  Data Length  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |
:  UTF-8-encoded CAUSE of event :
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.22. IAX UNKNOWN ❓

the IAX UNKNOWN IE is what you send when you get an IAX command you don't recognize 🙃 It means the received command was unknown or unrecognized. Its 1-octet data field holds the subclass of the frame that got rejected.

The IAX UNKNOWN IE MUST be sent with IAX UNSUPPORT messages 💅

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x17     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Rec'd Subclass|
+-+-+-+-+-+-+-+-+

8.6.23. MSGCOUNT 📫

the MSGCOUNT IE shows how many voicemail messages are waiting in a registered user's mailbox 📬 Its data field is 2 octets long. If it's set to all 1s, that means there's at least one message. Any other value packs the number of old messages into the high 8 bits and the number of new messages into the low 8 bits. Very efficient, very iconic 🧠

The IAX MSGCOUNT IE MAY be sent with IAX REGACK messages 🎀

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x18     |      0x02     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Old messages |  New messages |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.24. AUTOANSWER 📲

the AUTOANSWER IE asks for a call to be auto-answered when a NEW message comes in that includes it 🙋 Heads up, though: it's a request, and the remote peer can grant it or not. There's no data field, because just being there tells the whole story.

The AUTOANSWER IE MAY be sent with IAX NEW messages 💖

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x19     |      0x00     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.25. MUSICONHOLD 🎶

the MUSICONHOLD IE requests music-on-hold while a call is in the QUELCH state 🎧 Its data field is optional, and if it's there, it names the music-on-hold class to use, as UTF-8-encoded data. Without a data field, no class is specified, and the IE SHOULD be treated as a generic request for music-on-hold. If no MUSICONHOLD IE is received, music-on-hold is not requested, so no hold music for you 😌

The MUSICONHOLD IE MAY be sent with IAX QUELCH messages 🌈

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x1a     |  Data Length  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |
:  Optional Music On Hold Class :
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.26. TRANSFERID 🪪

the TRANSFERID IE is how you identify a transfer across all three peers in the transfer event 🔍 It carries a 4-octet number that SHOULD be unique for the whole duration of the transfer process. It's giving ID badge 🎟️

The TRANSFERID IE SHOULD be sent with IAX TXREQ and TXCNT messages, since it helps the peers in the transfer figure out which calls are which. It's not required, though, as long as the transferring peers can positively identify the calls without it 👑

                    1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x1b     |      0x04     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       4-octet transfer        |
|           identifier          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.27. RDNIS ✨

Okay bestie, the RDNIS (Redirected Dialed Number Identification Service) information element is how you tell your peer the referring DNIS 📞🦋 It carries UTF-8-encoded data, so your text is safe and sound 💜

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x1c     |  Data Length  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                               |
   :      UTF-8-encoded RDNIS      :
   |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.28. DATETIME ⏰🎀

The DATETIME information element tells the other side what time a message was sent 🕰️ Here's the tea: the header time-stamp starts at 0 for every single call, so it's not the real clock time. DATETIME is different because it's call-independent and shows the actual real-world time 💅

Its data field is four octets long, and it packs everything in like this:

  • the 5 least significant bits are seconds
  • the next 6 least significant bits are minutes
  • the next least significant 5 bits are hours
  • the next least significant 5 bits are the day of the month
  • the next least significant 4 bits are the month
  • the most significant 7 bits are the year

The year is offset from 2000, and the month is a 1-based index, so January == 1, February == 2, and so on 🌸 The timezone of the clock MUST be UTC so both peers stay on the same page 🌍 Nobody wants a confused call!!

The DATETIME information element SHOULD be sent with IAX NEW and REGACK messages 💖 Also, it's strictly informational, so it's a vibe check, not a rule 😌

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x1f     |      0x04     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     year    | month |   day   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  hours  |  minutes  | seconds |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.29. CALLINGPRES 💁‍♀️

The CALLINGPRES information element shows the calling presentation of a caller, so everyone knows how the caller wants to appear 👑 The data field is 1 octet long and holds a value from the table below.

The CALLINGPRES information element MUST be sent with IAX NEW messages 🫶

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x26     |      0x01     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Calling Pres. |
   +-+-+-+-+-+-+-+-+

Here are the valid calling presentation values 🧚

              +------+--------------------------------------+
              | FLAG | PRESENTATION                         |
              +------+--------------------------------------+
              | 0x00 | Allowed user/number not screened     |
              |      |                                      |
              | 0x01 | Allowed user/number passed screen    |
              |      |                                      |
              | 0x02 | Allowed user/number failed screen    |
              |      |                                      |
              | 0x03 | Allowed network number               |
              |      |                                      |
              | 0x20 | Prohibited user/number not screened  |
              |      |                                      |
              | 0x21 | Prohibited user/number passed screen |
              |      |                                      |
              | 0x22 | Prohibited user/number failed screen |
              |      |                                      |
              | 0x23 | Prohibited network number            |
              |      |                                      |
              | 0x43 | Number not available                 |
              +------+--------------------------------------+

For any additional IAX Calling Presentation values, go check the IANA Registry 🔍

8.6.30. CALLINGTON 🌈

The CALLINGTON information element indicates the calling type of number of a caller, following the ITU-T Recommendation Q.931 specifications 📚 The data field is 1 octet long and uses data from the table below.

The CALLINGTON information element MUST be sent with IAX NEW messages 💜

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x27     |      0x01     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Calling TON  |
   +-+-+-+-+-+-+-+-+

These are the valid calling type of number values from ITU-T Recommendation Q.931 🎀

                    +-------+-------------------------+
                    | VALUE | DESCRIPTION             |
                    +-------+-------------------------+
                    | 0x00  | Unknown                 |
                    |       |                         |
                    | 0x10  | International Number    |
                    |       |                         |
                    | 0x20  | National Number         |
                    |       |                         |
                    | 0x30  | Network Specific Number |
                    |       |                         |
                    | 0x40  | Subscriber Number       |
                    |       |                         |
                    | 0x60  | Abbreviated Number      |
                    |       |                         |
                    | 0x70  | Reserved for extension  |
                    +-------+-------------------------+

Any extra IAX Calling Type of Number values live in the IANA Registry, so check there too 🦋

8.6.31. CALLINGTNS 🌷

The CALLINGTNS information element indicates the calling transit network selected for a call 🛰️ The values follow ITU-T Recommendation Q.931 specifications. The data field is two octets long. The first octet stores the network identification plan in its least significant four bits, using the first table below, and the type of network in the next three least significant bits, using the second table below. The second octet stores the actual network identification as UTF-8-encoded data 💅

The CALLINGTNS information element MUST be sent with IAX NEW messages ✨

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x28     |      0x02     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | | TON | Plan  | UTF-8 Net ID  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here are the valid values for the data field of the 'calling tns' IE 🍓

Q.931 Network Identification Plan Values:

                +------+----------------------------------+
                | BITS | DESCRIPTION                      |
                +------+----------------------------------+
                | 0000 | Unknown                          |
                |      |                                  |
                | 0001 | Caller Identification Code       |
                |      |                                  |
                | 0011 | Data Network Identification Code |
                +------+----------------------------------+

Refer to the IAX Transit Network Identification IANA Registry for any additional values 🔍

Q.931 Type of Network Values:

              +------+--------------------------------------+
              | BITS | DESCRIPTION                          |
              +------+--------------------------------------+
              | 000  | User Specified                       |
              |      |                                      |
              | 010  | National Network Identification      |
              |      |                                      |
              | 011  | International Network Identification |
              +------+--------------------------------------+

Refer to the IAX Type of Network IANA Registry for any additional values 💖

8.6.32. SAMPLINGRATE 🎧

The SAMPLINGRATE information element tells a remote IAX peer the sampling rate, in hertz, of the audio data the peer will use when sending data 🎶 Its data field is 2 octets long.

If the SAMPLINGRATE information element is not specified, a default sampling rate of 8 kHz may be assumed 🌙

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      0x29     |      0x02     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Sampling Rate in Hertz    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.33. CAUSECODE ✨

okay so the CAUSECODE information element is basically the "why did this call get dumped?" reason 💅 It's the reason a call was REJECTed or HANGUPed, and it borrows its numbers from ITU-T Recommendation Q.931 🎀 The data field is one octet long and holds one entry from the table below 🍓

The CAUSECODE information element SHOULD be sent with HANGUP, REJECT, REGREJ, and TXREJ messages 🫶

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x2a     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Cause Code  |
+-+-+-+-+-+-+-+-+
+--------+----------------------------------------------------------+
| NUMBER | CAUSE                                                    |
+--------+----------------------------------------------------------+
| 1      | Unassigned/unallocated number                            |
|        |                                                          |
| 2      | No route to specified transit network                    |
|        |                                                          |
| 3      | No route to destination                                  |
|        |                                                          |
| 6      | Channel unacceptable                                     |
|        |                                                          |
| 7      | Call awarded and delivered                               |
|        |                                                          |
| 16     | Normal call clearing                                     |
|        |                                                          |
| 17     | User busy                                                |
|        |                                                          |
| 18     | No user response                                         |
|        |                                                          |
| 19     | No answer                                                |
|        |                                                          |
| 21     | Call rejected                                            |
|        |                                                          |
| 22     | Number changed                                           |
|        |                                                          |
| 27     | Destination out of order                                 |
|        |                                                          |
| 28     | Invalid number format/incomplete number                  |
|        |                                                          |
| 29     | Facility rejected                                        |
|        |                                                          |
| 30     | Response to status enquiry                               |
|        |                                                          |
| 31     | Normal, unspecified                                      |
|        |                                                          |
| 34     | No circuit/channel available                             |
|        |                                                          |
| 38     | Network out of order                                     |
|        |                                                          |
| 41     | Temporary failure                                        |
|        |                                                          |
| 42     | Switch congestion                                        |
|        |                                                          |
| 43     | Access information discarded                             |
|        |                                                          |
| 44     | Requested channel not available                          |
|        |                                                          |
| 45     | Preempted (causes.h only)                                |
|        |                                                          |
| 47     | Resource unavailable, unspecified (Q.931 only)           |
|        |                                                          |
| 50     | Facility not subscribed (causes.h only)                  |
|        |                                                          |
| 52     | Outgoing call barred (causes.h only)                     |
|        |                                                          |
| 54     | Incoming call barred (causes.h only)                     |
|        |                                                          |
| 57     | Bearer capability not authorized                         |
|        |                                                          |
| 58     | Bearer capability not available                          |
|        |                                                          |
| 63     | Service or option not available (Q.931 only)             |
|        |                                                          |
| 65     | Bearer capability not implemented                        |
|        |                                                          |
| 66     | Channel type not implemented                             |
|        |                                                          |
| 69     | Facility not implemented                                 |
|        |                                                          |
| 70     | Only restricted digital information bearer capability is |
|        | available (Q.931 only)                                   |
|        |                                                          |
| 79     | Service or option not available (Q.931 only)             |
|        |                                                          |
| 81     | Invalid call reference                                   |
|        |                                                          |
| 82     | Identified channel does not exist (Q.931 only)           |
|        |                                                          |
| 83     | A suspended call exists, but this call identity does not |
|        | (Q.931 only)                                             |
|        |                                                          |
| 84     | Call identity in use (Q.931 only)                        |
|        |                                                          |
| 85     | No call suspended (Q.931 only)                           |
|        |                                                          |
| 86     | Call has been cleared (Q.931 only)                       |
|        |                                                          |
| 88     | Incompatible destination                                 |
|        |                                                          |
| 91     | Invalid transit network selection (Q.931 only)           |
|        |                                                          |
| 95     | Invalid message, unspecified                             |
|        |                                                          |
| 96     | Mandatory information element missing (Q.931 only)       |
|        |                                                          |
| 97     | Message type nonexistent/not implemented                 |
|        |                                                          |
| 98     | Message not compatible with call state                   |
|        |                                                          |
| 99     | Information element nonexistent                          |
|        |                                                          |
| 100    | Invalid information element contents                     |
|        |                                                          |
| 101    | Message not compatible with call state                   |
|        |                                                          |
| 102    | Recovery on timer expiration                             |
|        |                                                          |
| 103    | Mandatory information element length error (causes.h     |
|        | only)                                                    |
|        |                                                          |
| 111    | Protocol error, unspecified                              |
|        |                                                          |
| 127    | Internetworking, unspecified                             |
+--------+----------------------------------------------------------+

Refer to the IAX Cause Codes IANA Registry for any additional values 📚

8.6.34. ENCRYPTION 🔐

the ENCRYPTION information element is the one that tells your bestie which encryption methods an IAX peer is cool with 🦋 The data field is a 2-octet bitmask, and each bit lines up with a method from the table below 💜

The ENCRYPTION information element MAY be sent with NEW and AUTHREQ messages 🌸

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x2b     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Encryption Methods       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The following table lists valid native encryption methods:

                     +--------+-------------+
                     | METHOD | DESCRIPTION |
                     +--------+-------------+
                     | 0x0001 | AES-128     |
                     +--------+-------------+

Refer to the IAX Encryption Methods IANA Registry for any additional values 🔑

8.6.35. CODEC PREFS 🎧

the CODEC PREFS information element is giving "here's what I like, in order" 🥰 It tells the peer which CODECs the calling peer prefers, listed from favourite to least favourite. The data field is a list of CODECs in the peer's order of preference, stored as UTF-8-encoded data ✨

The CODEC PREFS information element MAY be sent with NEW messages 💖

If the CODEC PREFS information element is absent, CODEC negotiation takes place via the CAPABILITY and FORMAT information elements 🧚

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x2d     |  Data Length  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |
:       CODEC Prefs Data        :
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.36. RR JITTER 📈

the Receiver Report (RR) JITTER information element is how you show the received jitter on a call, per [RFC3550] 🌈 The data field is 4 octets long and carries the current measured jitter 🎀

The RR JITTER information element MAY be sent with PONG messages 🫧

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x2e     |      0x04     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Received Jitter       |
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.37. RR LOSS ✨

Okay bestie, this one tracks how many frames got lost on a call, which is per [RFC3550] 🦋. The data field is 4 octets long. The first octet holds the percentage of frames lost, and the next 3 octets hold the count of lost frames 📊.

The RR LOSS information element MAY be sent with IAX PONG messages 💌

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x2f     |      0x04     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Loss Percent |               |
+-+-+-+-+-+-+-+-+  Loss Count   |
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.38. RR PKTS 🎀

The RR PKTS information element is here to tell you the total number of frames received on a call, per [RFC3550] 🌸. The data field is 4 octets long and holds the count of frames received 🍓.

The RR PKTS information element MAY be sent with IAX PONG messages 💜

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x30     |      0x04     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Frames Received Count      |
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.39. RR DELAY 🧚

RR DELAY is all about the maximum playout delay for a call, per [RFC3550] ⏱️. The data field is 2 octets long and says how many milliseconds a frame can be delayed before it MUST be discarded. That's a hard rule, no wiggle room 🚫

The RR DELAY information element MAY be sent with IAX PONG messages 🫶

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x31     |      0x02     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Maximum Playout Delay      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.40. RR DROPPED 💅

RR DROPPED reports the total number of dropped frames for a call, per [RFC3550] 💀. The data field is 4 octets long and carries the number of frames dropped 📉.

The RR DROPPED information element MAY be sent with IAX PONG messages ✨

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x32     |      0x04     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Total Frames Dropped     |
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.41. RR OOO 🌈

RR OOO is the number of frames received out of order for a call, per [RFC3550] 🔀. The data field is 4 octets long and carries that out-of-order count 🎯.

The RR OOO information element MAY be sent with IAX PONG messages 🦋

                     1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x33     |      0x04     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Frames Received       |
|          Out of Order         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.6.42. OSPTOKEN 🔐

OSPTOKEN carries tokens from the European Telecommunications Standards Institute (ETSI) Technical Specification 101 321 [OSP], which is also known as the Open Settlement Protocol or OSP 🏆. These tokens are used to handle authorization, authentication and account support for IAX through the OSP protocol 👑. The first octet of the data field is the OSP token block index, and it starts counting from 0 🔢.

The OSPTOKEN information element MAY only be sent with IAX NEW messages 🌸. If the receiver doesn't support the token, it just gets ignored, no drama 🙈

                            1
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |      0x34     |  Data Length  |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Block Index  |               |
       +-+-+-+-+-+-+-+-+               +
       |        OSP Token Block        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

8.7. Media Formats 🎶

Media Format Values

+------------+-----------------+------------------------------------+
| SUBCLASS   | DESCRIPTION     | LENGTH CALCULATION                 |
+------------+-----------------+------------------------------------+
| 0x00000001 | G.723.1         | 4-, 20-, and 24-byte frames of 240 |
|            |                 | samples                            |
|            |                 |                                    |
| 0x00000002 | GSM Full Rate   | 33-byte chunks of 160 samples or   |
|            |                 | 65-byte chunks of 320 samples      |
|            |                 |                                    |
| 0x00000004 | G.711 mu-law    | 1 byte per sample                  |
|            |                 |                                    |
| 0x00000008 | G.711 a-law     | 1 byte per sample                  |
|            |                 |                                    |
| 0x00000010 | G.726           |                                    |
|            |                 |                                    |
| 0x00000020 | IMA ADPCM       | 1 byte per 2 samples               |
|            |                 |                                    |
| 0x00000040 | 16-bit linear   | 2 bytes per sample                 |
|            | little-endian   |                                    |
|            |                 |                                    |
| 0x00000080 | LPC10           | Variable size frame of 172 samples |
|            |                 |                                    |
| 0x00000100 | G.729           | 20-byte chunks of 172 samples      |
|            |                 |                                    |
| 0x00000200 | Speex           | Variable                           |
|            |                 |                                    |
| 0x00000400 | ILBC            | 50 bytes per 240 samples           |
|            |                 |                                    |
| 0x00000800 | G.726 AAL2      |                                    |
|            |                 |                                    |
| 0x00001000 | G.722           | 16 kHz ADPCM                       |
|            |                 |                                    |
| 0x00002000 | AMR             | Variable                           |
|            |                 |                                    |
| 0x00010000 | JPEG            |                                    |
|            |                 |                                    |
| 0x00020000 | PNG             |                                    |
|            |                 |                                    |
| 0x00040000 | H.261           |                                    |
|            |                 |                                    |
| 0x00080000 | H.263           |                                    |
|            |                 |                                    |
| 0x00100000 | H.263p          |                                    |
|            |                 |                                    |
| 0x00200000 | H.264           |                                    |
+------------+-----------------+------------------------------------+

Refer to the IANA Registry for any additional IAX Media Format values 📚 That's where the rest of the codes live, so check there 🗂️

9. Example Message Flows 🎬

This section is all about call flow diagrams for some of the different kinds of IAX calls you can make 📞. In each diagram, the '=' character stands for a Full Frame and the '-' character stands for a Mini Frame 💫. Notes that apply to a generic call can go right next to each diagram 📝

9.1. Ping/Pong 🏓

PING->PONG

       Peer A                                Peer B
        ________________________________________
       |                                        |
  T    |                                        |
  i    |  ===PING============================>  |
  m    |                                        |
  e    |  <============================PONG===  |Has same time-stamp
       |                                        | as received PING.
  |    |  ===ACK=============================>  |Has same time-stamp
  |    |                                        | as received PONG
 \ /   |________________________________________| and original PING.

9.2. Lagrq/Lagrp 🌷

LAGRQ->LAGRP

       Peer A                                Peer B
        ________________________________________
       |                                        |
  T    |                                        |
  i    |  ===LAGRQ===========================>  |
  m    |                                        |
  e    |  <===========================LAGRP===  |Same time-stamp as
       |                                        | received LAGRQ.
  |    |  ===ACK=============================>  |Same time-stamp as
  |    |                                        | received LAGRP and
 \ /   |________________________________________| original LAGRQ.

9.3. Registration 🔑

Registration of an IAX Peer 🤝

     Registrant  A                     Registrar B
        ________________________________________
       |                                        |
  T    |  ===REGREQ==========================>  |
  i    |                                        |
  m    |  <=========================REGAUTH===  |
  e    |                                        |
       |  ===REGREQ==========================>  |
  |    |                                        |
  |    |  <==========================REGACK===  |
\ | /  |                                        |
 \|/   |  ===ACK=============================>  |
       |                                        |
       |________________________________________|

9.4. Registration Release 🚪

Registration Release 💫

     Registrant A                        Registrar B
        ________________________________________
       |                                        |
  T    |  ===REGREL==========================>  |
  i    |                                        |
  m    |  <=========================REGAUTH===  |
  e    |                                        |
       |  ===REGREL==========================>  |
  |    |                                        |
  |    |  <==========================REGACK===  |
\ | /  |                                        |
 \|/   |  ===ACK=============================>  |
       |                                        |
       |________________________________________|

9.5. Call Path Optimization ✨

okay so this one is giving IAX Transfer 💅 three peers, L, C, and R, all passing messages back and forth so the call can hop onto a new path. the timeline runs top to bottom, and it's honestly so satisfying to follow 🦋

        Peer L         Peer C                Peer R
         ________________________________________
        |                 |                      |
   T    |                 |                      |
        | <== TXREQ =====[*]== TXREQ =========>  |C requests transfer
   i    |                 |                      |
        | ========================== TXCNT  ==>  |L sends to R
   m    |                 |                      |
        | <========================= TXACC  ==== |R replies
   e    |                 |                      |R sends Media
        |                 |                      | to L
   |    |                 |                      |
   |    | = TXREADY ====> |                      |L tells C 'ready'
   |    |                 |                      | C stops media to L
   |    |                 |                      |
   |    | <== TXCNT ===========================  |L sends to R
   |    |                 |                      |
   |    | === TXACC ===========================> |R replies
  \ /   |                 |                      |
        |                 | <== TXREADY ======   |R tells C 'ready'
        |                 |                      | C stops media to R
        |                 |                      |
        | <== TXREL =====[*]== TXREL =========>  |C Releases
        |                                        |
        |________________________________________|

9.6. IAX Media Call ✨

this one is the complete end-to-end IAX media exchange 🎀 from the first NEW all the way to the HANGUP, with the optional authentication step, the ringing, the answer, and all the voice frames in between. the notes underneath explain the time-stamp stuff, which is kind of a big deal 🙈

        Peer A                            Peer B
         ________________________________________
        |                                        |
        |  ====NEW============================>  |
   T    |  <=========================AUTHREQ===  |If authentication
        |                                        |   specified.
   i    |  ====AUTHREP========================>  |
   m    |  <==========================ACCEPT===  |
   e    |  ====ACK============================>  |
        |                                        |
   |    |  <=============Voice (Full Frame)===   |
   |    |  ====ACK===========================>   |
   |    |                                        |
   |    |  <---------Voice Mini Frame (ring)--   |
   |    |  <---------Voice Mini Frame (ring)--   |
   |    |                                        |
 \ | /  |  <=========================RINGING===  |
  \|/   |  ====ACK============================>  |
        |                                        |
        |  <---------Voice Mini Frame (ring)--   |
        |  <---------Voice Mini Frame (ring)--   |
        |                                        |
        |  <==========================ANSWER===  |
        |  ====ACK============================>  |
        |                                        |
        |  ====Voice (Full Frame)=============>  |
        |  <=============================ACK===  |
        |                                        |
        |                                        |
        |  <-----------Voice Mini Frames------>  |  exchange occurs
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <-----------Voice Mini Frames------>  |
        |                                        |
        |                                        |
        |  ====Voice (Full Frame)=============>  |  (note 1)
        |  <===ACK=============================  |  (note 2)
        |                                        |  (every 65536 ms)
        |  <=============Voice (Full Frame)====  |  (note 3)
        |  ====ACK============================>  |
        |                                        |
        |                                        |
        |  <-----------Voice Mini Frames------>  |
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <-----------Voice Mini Frames------>  |
        |                                        |
        |                                        |
        |  ====HANGUP=========================>  |  Either can hangup
        |  <=============================ACK===  |
        |________________________________________|

Notes for the diagram above:

Note 1: Mini Frames carry the low 16 bits of the peer's
        32-bit time-stamp.
Note 2: Full frames resync the 32-bit time-stamp when the 16-bit
        time-stamp overflows.
Note 3: Each side has its own 32-bit time-stamp so each side needs
        to sync at 16-bit overflow.
the time-stamp bit is the sneaky part, bestie. mini frames only carry the low 16 bits, so the full frames have to do the resync dance 🌈

9.7. IAX Media Call via an IAX Device ✨

so an IAX peer doesn't have to keep a full dialplan 🧚 if a user wants to dial from an IAX peer that doesn't do its own call switching, this flow shows what the whole transaction can look like. peer A is the IAX device and peer B is the dialplan server doing the heavy lifting 💜

        Peer A (IAX Device)                 Peer B (Dialplan Server)
         ________________________________________
        |                                        |
        |  ====NEW============================>  |
   T    |  <=========================AUTHREQ===  |  If auth specified
   i    |  ====AUTHREP========================>  |
   m    |  <==========================ACCEPT===  |
   e    |  ====ACK============================>  |
        |                                        |
        |  ====DPREQ==========================>  |  (Note 1)
   |    |  <===========================DPREP===  |
   |    |                                        |
   |    |  ====DIAL===========================>  |
   |    |  <========================PROGRESS===  |
   |    |  ====ACK============================>  |
 \ | /  |  <==========================ANSWER===  |
  \|/   |  ====ACK============================>  |
        |                                        |
        |  ====Voice (Full Frame)=============>  |
        |  <=============================ACK===  |
        |  <=============Voice (Full Frame)====  |
        |  ====ACK============================>  |
        |                                        |
        |                                        |
        |  <-----------Voice Mini Frames------>  |  Media exchange
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <-----------Voice Mini Frames------>  |
        |                                        |
        |                                        |
        |  ====Voice (Full Frame)=============>  |  (note 2)
        |  <===ACK=============================  |  (note 3)
        |                                        |  (every 65536 ms)
        |  <=============Voice (Full Frame)====  |  (Note 4)
        |  ====ACK============================>  |
        |                                        |
        |                                        |
        |  <-----------Voice Mini Frames------>  |
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <---               .            --->  |
        |  <-----------Voice Mini Frames------>  |
        |                                        |
        |                                        |
        |  ====HANGUP=========================>  |  Either can hangup
        |  <=============================ACK===  |
        |________________________________________|

Notes for the diagram above:

Note 1: There will be multiple DPREQ/DPREPs per call unless
        dialed number is 1 digit long.
Note 2: Mini Frames carry the low 16 bits of the peer's
        32-bit time-stamp.
Note 3: Full Frames resync the 32-bit time-stamp when the 16 bit
        time-stamp overflows.
Note 4: Each side has its own 32-bit time-stamp so each side needs
        to sync at 16-bit overflow.

10. Security Considerations 🔐✨

Okay bestie, IAX is a binary protocol for setting up point-to-point call legs that carry both media and signaling. That makes it simpler to secure than the more general-purpose VoIP protocols 💅 but security is still a tough job, and you have to look at various parts of the protocol to spot the risks 👀.

Registration 🎀

Registration needs really careful attention. Older protocol versions supported cleartext passwords, but that feature has been eliminated 🙅‍♀️. The MD5 and RSA options are way more secure. The IAX protocol doesn't specify this, but some implementations limit each account to one registrant. If a second registrant shows up with the same credentials, they overwrite the first and receive the calls meant for that user 😱. Theft of service is trivial once a malicious caller can authenticate 💀. Plus, distinct cause codes come back for erroneous registration attempts, so an attacker can tell existing users from nonexistent ones in a registration system. That opens the door to a possible directory harvest attack 🕵️‍♀️.

Replay and Challenges 🦋

The IAX protocol protects against message replay with a challenge-response method. The IAX registrar or server challenges each call or registration with an arbitrary MD5 or RSA challenge. The response and the authorization that follows rely on knowing a shared secret. The server usually picks its challenges with a random-number-based technique, so the challenge set is large and replay is highly unlikely 🔥.

Servers are allowed to skip the challenge process I just described, but that's not recommended 🙈. This open approach is inherently insecure and does nothing to prevent unauthorized usage.

Call Encryption 🔑

Call encryption in IAX starts out using static keys. Once they're negotiated, the key may be changed for the rest of the call. Once the initial key is compromised, though, all subsequent calls are open to interception 😭. A more secure implementation would update the key frequently and as early as practical during each call 🌈.

Eavesdropping and Man-in-the-Middle 👀

IAX is also susceptible to eavesdropping. Call Detail, meaning who is calling whom, is sent in unencrypted binary whether or not the call is going to be encrypted. Without encryption, call content (the audio and video) can be easily intercepted. The good news is that this content stays protected if the call is encrypted 🛡️.

Man-in-the-middle attacks are a threat to IAX when encryption isn't used. This kind of attack lets someone insert, delete, and modify messages, so a call can be redirected, or the audio or video can be replaced in either or both directions, for the whole call or any portion of it 😳. If encryption is used, the call is protected end to end 💜.

Note: an initial NEW message in an encrypted call is unencrypted and could be changed. However, this is limited to a denial-of-service (DoS) attack, because subsequent messages containing the same address information are redelivered in an encrypted form.

Denial of Service 🚨

DoS attacks can take at least two forms in IAX. The first is simply overloading the peers with bogus requests. A carefully implemented IAX peer would spot this situation and raise an alarm or take other protective action 🚓.

The second form targets an existing call with an engineered attack. Think injecting media, causing excess processing by inserting out-of-order packets, and sending commands such as hangup or transfer 😤. These attacks need close monitoring of the binary channel to work, because the message sequence numbers would have to be synchronized with the protocol exchange 🧐.

Of course, lower-layer security with Datagram Transport Layer Security (DTLS) [RFC4347], or IPsec [RFC4301], would address many of these potential issues ✨.

Unicode [RFC3629] and stringprep [RFC3454] security considerations also apply 📖.


11. IANA Considerations 📋

To make it easier to extend the IAX protocol in an orderly way, several IANA registries have been created. These registry requests are found in [RFC5457]. In addition, the "iax" URI scheme has been registered; see Section 5. IAX has also been assigned a well-known UDP port number, 4569 🦋.


12. Implementation Notes 🛠️

The original IAX implementation was in Asterisk, the open-source PBX, but [wikipedia] lists thirteen other publicly available implementations at the time of this writing 🌸. Some of these implementations used draft versions of this specification. Many others were built using the Asterisk source code as their only specification. That approach is definitive, but it's very hard to figure out the protocol's higher-level logic and optimize it for a particular programming language or application environment 😵‍💫. Interoperability of these implementations cannot be guaranteed.

Besides the trials and tribulations of reverse engineering the source code to make a new implementation, the key lessons learned involve threads, support of international character sets, security, and better controls to limit interference during DoS attacks 📚.

The current Asterisk implementation has a limited number of IAX worker threads, so its scalability is limited. It can, however, run on low-end machines where threads may not be freely available 💻. Improving the threading model will undoubtedly improve performance 🚀.

Internationalization and localization weren't originally addressed by most implementations. They were always on the IAX developers' road map, but never a priority 🌍. While creating this document, we formalized support for UTF-8 encoding to better support internationalization and localization 💖.

When it comes to security, many IAX implementations permit cleartext authentication. That method is not secure and should not be used 🚫.

Recently, some issues have been raised about server robustness under DoS attack. IAX servers that support unauthenticated requests can receive the equivalent of a SYN attack 😬. To mitigate the impact, various controls can be added to limit the number of unauthenticated calls and the number of calls per user. Other approaches are also suggested, like transferring the call to another, more protected port, or using IP rate limiting when excessive failures are detected 🛡️.

Lastly, because the protocol and implementations are open, IAX is very easy to extend 🧩. That makes Postel's Robustness Principle, "Be conservative in what you do, be liberal in what you accept from others", essential to any successful IAX implementation 👑.


13. Acknowledgments 💌

This work was supported by Internet Foundation Austria 🇦🇹. The authors would like to thank Birgit Arkesteijn, Marc Blanchet, Mohamed Boucadair, Steve Kann, Olle Johansson, Alexander Mayrhofer, Tim Panton, and Peter Saint-Andre for their extensive review and technical input 🫶. We would also like to thank Jim Dalton, Christopher DeMarco, Frank Ellermann, Daniel Medeiros, Dimitri E. Prado, Leif Madson, and Tilghman Lesher for their support and suggestions 🌷.


14. References 📚

14.1. Normative References

[AES]        U.S. Department of Commerce/N.I.S.T., "FIPS-197,
             Announcing the Advanced Encryption Standard",
             November 2001.

[E164]       ITU-T, "The International Public Telecommunication
             Number Plan",  Recommendation E.164, May 1997.

[OSP]        European Telecommunications Standards Institute,
             "Telecommunications and Internet Protocol  Harmonization
             Over Networks (TIPHON) Release 4;  Open Settlement
             Protocol (OSP) for  Inter-Domain pricing, authorization
             and usage exchange", November 2003.

[RFC1321]    Rivest, R., "The MD5 Message-Digest Algorithm",
             RFC 1321, April 1992.

[RFC1851]    Karn, P., Metzger, P., and W. Simpson, "The ESP Triple
             DES Transform", RFC 1851, September 1995.

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

[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.

[RFC3447]    Jonsson, J. and B. Kaliski, "Public-Key Cryptography
             Standards (PKCS) #1: RSA Cryptography Specifications
             Version 2.1", RFC 3447, February 2003.

[RFC3454]    Hoffman, P. and M. Blanchet, "Preparation of
             Internationalized Strings ("stringprep")", RFC 3454,
             December 2002.

[RFC3491]    Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep
             Profile for Internationalized Domain Names (IDN)",
             RFC 3491, March 2003.

[RFC3550]    Schulzrinne, H., Casner, S., Frederick, R., and V.
             Jacobson, "RTP: A Transport Protocol for Real-Time
             Applications", STD 64, RFC 3550, July 2003.

[RFC3629]    Yergeau, F., "UTF-8, a transformation format of ISO
             10646", STD 63, RFC 3629, November 2003.

[RFC3986]    Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
             Resource Identifier (URI): Generic Syntax", STD 66,
             RFC 3986, January 2005.

[RFC4347]    Rescorla, E. and N. Modadugu, "Datagram Transport Layer
             Security", RFC 4347, April 2006.

[RFC4647]    Phillips, A. and M. Davis, "Matching of Language Tags",
             BCP 47, RFC 4647, September 2006.

[RFC5234]    Crocker, D. and P. Overell, "Augmented BNF for Syntax
             Specifications: ABNF", STD 68, RFC 5234, January 2008.

[RFC5646]    Phillips, A., Ed., and M. Davis, Ed., "Tags for
             Identifying Languages", BCP 47, RFC 5646, September
             2009.

[html401]    Jacobs, I., Raggett, D., and A. Hors, "HTML 4.01
             Specification", World Wide Web Consortium
             Recommendation REC-html401-19991224, December 1999,
             <http://www.w3.org/TR/1999/REC-html401-19991224>.

14.2. Informative References ✨

okay bestie, this is the extra reading list 📚💜 if you wanna go deeper on anything, these are where to look

  • [PKCS] RSA Laboratories, "PKCS #1 v2.0: RSA Cryptography Standard", October 1998. 🔐
  • [RFC3174] Eastlake, D. and P. Jones, "US Secure Hash Algorithm 1 (SHA1)", RFC 3174, September 2001. 🧂
  • [RFC3435] Andreasen, F. and B. Foster, "Media Gateway Control Protocol (MGCP) Version 1.0", RFC 3435, January 2003. 📞
  • [RFC3525] Groves, C., Pantaleo, M., Anderson, T., and T. Taylor, "Gateway Control Protocol Version 1", RFC 3525, June 2003. 🌉
  • [RFC3761] Faltstrom, P. and M. Mealling, "The E.164 to Uniform Resource Identifiers (URI) Dynamic Delegation Discovery System (DDDS) Application (ENUM)", RFC 3761, April 2004. 🔢
  • [RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, December 2005. 🛡️
  • [RFC4395] Hansen, T., Hardie, T., and L. Masinter, "Guidelines and Registration Procedures for New URI Schemes", BCP 35, RFC 4395, February 2006. 🗂️
  • [RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session Description Protocol", RFC 4566, July 2006. 🎙️
  • [RFC4733] Schulzrinne, H. and T. Taylor, "RTP Payload for DTMF Digits, Telephony Tones, and Telephony Signals", RFC 4733, December 2006. 🎹
  • [RFC4734] Schulzrinne, H. and T. Taylor, "Definition of Events for Modem, Fax, and Text Telephony Signals", RFC 4734, December 2006. 📠
  • [RFC5125] Taylor, T., "Reclassification of RFC 3525 to Historic", RFC 5125, February 2008. 🕰️
  • [RFC5457] Guy, E., "IANA Considerations for IAX: Inter-Asterisk eXchange Version 2", RFC 5457, February 2010. 🧾
  • [wikipedia] Wikipedia, "Inter-Asterisk eXchange", http://en.wikipedia.org/wiki/IAX. 🌍

Authors' Addresses ✨

Meet the squad who built this 🫶 Here's how to reach each of them:

Mark A. Spencer
Digium, Inc.
445 Jan Davis Drive NW
Huntsville, AL  35806
US

Phone: +1 256 428 6000
EMail: markster@digium.com
URI:   http://www.digium.com/


Brian Capouch
Saint Joseph's College
PO Box 909
Rensselaer, IN  47978
US

Phone: +1 219 866 6114
EMail: brianc@saintjoe.edu


Ed Guy (editor)
Truphone
12 Williams Rd
Chatham, NJ  07928
US

Phone: +1 973 437 4519
EMail: edguy@emcsw.com
URI:   http://www.truphone.com/


Frank Miller
Cornfed Systems, LLC
3476 Dayton Street
Denver, CO  80238
US

Phone: +1 410 404-8790
EMail: mail@frankwmiller.net
URI:   http://www.sipuseragent.net
Kenneth C. Shumard
3818 N Lakegrove Way
Boise, ID  83713
US

Phone: +1 208 724 7801
EMail: kshumard@gmail.com
📦 where this page comes from