Register Log in

Ministry of Innovation / Business of Technology

VoIP in-depth: An introduction to the SIP protocol, Part 1

As a follow-up to our previous SIP primer, Ars takes you deep inside the …

In our last VoIP installment, we looked at the main reasons why SIP has become a widely adopted protocol, but we left details of the protocol's inner workings fairly vague. This article will drill down into the way the Session Initiation Protocol (SIP) works, and it should serve as a good starting point for really learning SIP. If you haven't already done so, you are encouraged to read the previous article, although it's not a prerequisite. This introduction also covers the latest SIP extensions and changes, so it gives a complete view of the protocol's current state, rather than just the basic, underlying RFC.

Session Initiation Protocol (SIP) is a VoIP signaling protocol. As its name suggests, it has everything to do with setting up sessions, which means it has the responsibility for starting a session after you dial a number (or double-click, in some cases). As such, SIP's role also includes maintaining user registrations with a server, defining session routing, handling various error scenarios, and, of course, modifying and tearing down sessions.

We'll present this introduction in two parts. In the first part, we'll focus on the SIP foundation layers. These layers allow creating a network of SIP servers. In the next article, we will go through the way a phone communicates with the rest of the world using this server network, based on the same foundation layers.

SIP Foundations

Message Structure

SIP shares the same message structure as HTTP and RTSP. As a result, most of the text description here would fit these protocols as well. Each message is either a request or a response. All messages are text-based and have the following form:

  • First line
  • Headers
  • Empty line
  • Optional body

The first line is different for a request and a response. A request's first line uses the following format:

<method (request type)> <URI (address/resource)> <version>

For example, a SIP request's first line can be:


A response comes in the form of:

<version> <code> <reason phrase>

The version is the same in all messages. The code is a 3-digit value, and the reason phrase could be any text describing the nature of the response. A proper first line in the response could be:

SIP/2.0 200 OK

It's easy to scan the first characters of a message to detect whether it's a request or a response ("/" is not a valid character for the method field, therefore even a generic parser could differentiate a request from a response).

Next come the headers of the message. Some headers contain vital information and thus are mandatory, but many headers are optional. Each header has a name and a value, and some have parameters. For example:


Contact is the header name, is the value, and expires=2000 is a parameter. Other parameters may appear separated by semicolons.

Some headers may appear just once in a message, and some may appear multiple times. An equivalent approach to using multiple headers is to separate each value-parameter set with a comma. Some headers have a compact form for which the header name is shorter. For example, you can use "m" instead of "Contact".

After the last header, there's an empty line followed by the body of the message. The body could be anything, even binary information. The header Content-Type specifies the type of the message body. In order to know the length of the body, you have to look at the Content-Length header. (If the transport type is UDP, then the Content-Length header is not mandatory. It is, however, mandatory for TCP). One common use of the body is to encapsulate the media negotiation protocol within the SIP message.

That's pretty much what you need to know in order to understand the basic structure of SIP. It is rather straightforward, and anyone who is already familiar with protocols that have similar structure will feel right at home. Of course, we still have to understand what this text means and what a SIP device should do with the messages it sends and receives.

Transport Types

By default, SIP messages are sent on port 5060 if they're unencrypted. Encrypted messages are sent over port 5061. One can specify a port other than the default within the SIP address and override this default value.

SIP mandates support for both UDP and TCP, but it can successfully operate on practically any transport type. It defines different behavior per transport only when the characteristics of the specific transport require it to do so. For example, UDP does not guarantee delivery, so SIP retransmits the messages. In TCP, such retransmission is really unnecessary (and confusing), so no one should retransmit a message. For the most part, other than the transaction layer (detailed in the next sub-section), almost no other component changes its behavior due to the transport.

In fact, because SIP operates hop-by-hop (clients do not usually communicate directly, but rather use proxies along the signaling path to send and receive messages), each hop could change the transport type. So a client may receive a message over TCP even if the original message was sent over UDP. SIP's transport type independence enables the possibility of defining new transport types that were not originally included when SIP itself was first defined. For example, RFC 4158 is a very short RFC that defines SIP over SCTP.

For connection-based transports (e.g., TCP and SCTP), the state of the connections is maintained. Connections are kept open and reused to save time and resources. The recommendation is to keep a connection open for at least 32 seconds after the last message, but in practice it's application-defined. Because there is no defined limit for the number of different SIP messages that one can send on a connection, two devices such as proxies usually have one or very few connections between them.

NAT vs. VoIP

One of the main challenges that VoIP protocols have encountered, and SIP is no exception, is the existence of NAT devices. NATs usually aggregate several IP addresses (in many cases within a private network) to a few external IP addresses, mapping different traffic from different IP addresses to different ports. (This is a very simplistic description of NATs; there are in fact several ways NATs can work, but this is a common one that's easy to describe). In order to map different addresses to IP and ports, NATs usually maintain a dynamic mapping table. If traffic from with port 5060 maps to a public IP address with port 10000, the NAT will keep this mapping as long as it has a flow of packets from that address. If the flow stops, the NAT will remove this mapping after a configurable amount of time to allow another internal IP and port to use the external IP and port combination.

VoIP's problem arises because signaling protocols are as minimalistic as possible in terms of traffic. In order to allow the rest of the world to locate a device, the device first registers by sending a REGISTER request. A response from the registrar accepting this registration will usually tell the device that its registration is valid for a long time, most commonly an hour.

Now, suppose a NAT is located between the client and the server. When the REGISTER request is sent, the NAT maps the device's internal IP and port to an external one. When the response is sent back, the NAT has the proper mapping to the original IP and port. If the client does not send any packets to the server (for example, does not make a call), the NAT may remove the mapping it created during the registration. The outcome of this scenario is that incoming calls cannot reach the client. The proxy server receiving the request to the registered client cannot reach the internal IP address without the NAT mapping.

It's because of this NAT issue that RFC 5626 was introduced. This RFC defines the techniques that a client can use to maintain the NAT mapping. It introduces the concept of a flow that should be maintained by the registering client. The client sends two empty lines (carriage return and line feed, or CRLF) on connection-oriented flow (TCP and SCTP) and expects to receive from the server a single empty line as a response. For connection-less transports, the client maintains the flow by using STUN (defined by RFC 5389).

Listing image by Flickr: smileham

Expand full story

12 Reader Comments

  1. I LOVE ARS.
    3 posts | registered
  2. KTAS FTW!!

    That image is of an old telephone from KTAS which is an acronym for Kjøbenhavns Telefon Aktieselskab (Copenhagen's Telephone Company PLC approximately) was the old danish regional (national?) telephone company. This is from back when we only had one telephone company to choose from and you got your phone with your number. If it broke it got exchanged for free as it was still owned by KTAS. Anyways, this probably doesn't make much sense to anyone else here but that image really took me back to my teens – even if the phone in the picture is quite a bit older than me. Smile
    2627 posts | registered
  3. Not bad and once IPv6 is implemented that should reduce the size of the SIP stack.
    15361 posts | registered
  4. Yeah I recognised the KTAS phone immediately too. It was from back when we had 3 companies covering 3 different parts of Denmark.

    They were later joined into one company and sold to Ameritech all the while the market was opened up.

    You didn't AFAIK need to use an official phone since you had to pay a monthly rent for it, I bought my own back when I was doing BBS stuff, which worked fine.


    At least that was true for Fyns Telefon (my regional provider), but the rules the three companies between was a bit different, maybe KTAS did give you a rent free phone.

    This comment was edited by Hinton on January 25, 2010 08:34
    11376 posts | registered
  5. quote:
    Originally posted by Hinton:

    Well, I was living at home with my parents at that time, so wasn't paying the bill, so it could be either. I just remember the free exchange whenever it broke.
    2627 posts | registered
  6. Nice. I've been on the outskirts of VoIP forever and have been meaning to look for content to get me to jump into learning about it. This looks like just the content I was looking for. This will take awhile to digest, but I look forward to it. Smile
    796 posts | registered
  7. If only SIP was that simple. The article relies on the RFC, but unfortunately SIP is almost as quirky as HTML, and the RFC is not enough to be compatible with the real world.
    979 posts | registered
  8. In the last example, why isn't the 486 sent back to the originating phone? If it sends out an INVITE, and then gets a 200 OK back, it's going to think the far end has picked up, isn't it?
    2657 posts | registered
  9. quote:
    Originally posted by LargeSock:

    That's correct. The use case is a single user registered with 2 devices. For example, one device is a mobile phone and the other is a fixed car phone with speaker. When the user is talking while driving on his car phone and receives an incoming call, the car phone would respond with 486 busy (let's ignore the possibility of call-waiting). However, the mobile phone is available and rings. The driver could ask a passenger to answer the call. Another option is to reject the call on the mobile device (or wait for timeout) in which case the proxy would forward an error response.

    Therefore, if the passenger answers the phone, a call does take place.I had this exact scenario a few days ago. The phones were not SIP based, but this article shows how SIP supports this possibility. A proxy would usually wait for the most appropriate response before forwarding it. However, a 2xx response means a session starts and thus it is forwarded even if other forked requests are pending a final response.
    6 posts | registered
  10. quote:
    Originally posted by ayelao:

    Yeah, I'm in the same boat. I've gotten through it once and I probably know just enough to hurt myself. But a great article all the same.
    2499 posts | registered
  11. Nice article. I recently started looking at sipdroid for my android handset. The sidroid docs recommend using as a proxy to your primary SIP server because it has been tweaked to handle a handset on a mobile connection (where IP drops in and out and changes address). I don't suppose anyone has any information on what they did? I'd rather not route my phone calls through the US, even if it is only signalling.
    161 posts | registered
  12. SIP based phone calls can be made for example with VoIP telephones.
    If these telephones are part of a telephone system they need a SIP account created on a SIP server. This handles the calls.
    This page can help you more:
    This page explains and illutsrates SIP server and how it is used with Ozeki Phone System XE.
    1 post | registered

You must to comment.

Need to register for a new account?

If you don't have an account yet it's free and easy.