The first release of nearly everything typically leaves something to be desired. Not only are there the inevitable bugs, but it’s nearly impossible to think through every use case that might be applied. This was clearly true with SIP. When I first began working with SIP in the late 1990’s there were quite a few holes and areas that weren’t quite thought through all that well. For instance, the first incarnation of SIP didn’t have the Refer message and transfer was implemented with a header in the Bye message. That header, which I recall as being called “bye-also,” directed the transferred party to hang up and place new call. It was clumsy at best and disappeared once Refer came along.
Another hole was how provisional responses were handled. As you may know, a provisional response is sent after a session has been initiated, but before it has been established. Provisional responses fall into the 1xx class of responses. The 1xx class of responses consists of 100 Trying, 180 Ringing, 182 Queued, and 183 Session in Progress. There is no limit to the number of provisional responses you might receive before a session is established with a final response (2xx through 6xx).
Not too long after SIP was developed a problem arose with provisional responses. There was no way of knowing if a provisional response was ever received. This was especially true with an unreliable, datagram protocol like UDP. A user agent server (UAS) might send a 183 Session in Progress in order to play an announcement to a user agent client (UAC), but the data network could drop the message and the UAS would never know that it wasn’t received. Thus, the Provisional Response Acknowledgement, or Prack message, was created.
The idea behind Prack is that the recipient of a 1xx response message informs the sender that the message was received and is being acted upon. That way the sender can know that the 180 Ringing message that it sent has caused some form of alerting to occur (i.e. a ringing phone).
The mechanics behind a Prack aren’t that difficult to understand once you learn about a few constructs that have been added to SIP. First, Prack messages aren’t automatically sent. The UAC needs to advertise that it supports Prack messages by adding a “Supported” header to an Invite message. Specially, it adds a Supported header with the value of 100Rel. For example,
Next, the UAS adds Require and Response Sequence (RSeq) headers to every provisional response it wants acknowledged. Every RSeq header will contain a numeric value that identifies a specific response message. For example, the sender might add the following to headers to 180 Ringing provisional response.
Upon receipt of that response message, the SIP UAC will reply with a Prack message containing a Response Acknowledge (RAck) header with the same RSeq value. For instance, if a 180 Ringing is received with an RSeq of 145, the Prack will contain an RAck header with the value of 145. The UAC responds back with a 200 OK to complete the acknowledgement.
The following message flow is an example of a Prack transaction.
UAC sends: INVITE (Supported: 100Rel)
UAS sends: 180 Ringing (Required: 100Rel, RSeq: 145)
UAC sends: PRACK (CSeq: 1 PRACK, RAck: 145)
UAS sends: 200 Ok (CSeq: 1 PRACK)
That’s really all there is to Prack. Will it be the last “fix” to SIP? Absolutely not. As SIP acceptance grows and it is applied in ways that the original developers never envisioned, there will be new headers, request types, and reference call flows.