RFC 3486

Compressing the Session Initiation Protocol (SIP)

πŸ“… published February 2003, from ietf

RFC 3486: Compressing the Session Initiation Protocol (SIP) πŸ’–

Okay bestie, the title block first πŸŽ€ This one is by G. Camarillo from Ericsson, filed in the Network Working Group in February 2003. It's a Standards Track doc, so it's an actual protocol spec and not just a discussion piece ✨ The block doesn't list any RFCs it obsoletes or updates, so this one stands on its own πŸ¦‹

Here's the plan: this doc is about teaching SIP how to say "hey, I'd love compressed messages, thank you" 🧚 It also explains when it's actually okay to send compressed SIP messages to another SIP entity πŸ’…

Here's the table of contents, exactly as it appears in the original:

1.   Introduction ...............................................  2
2.   Overview of operation ......................................  3
3.   SigComp implementations for SIP ............................  3
4.   Sending a Request to a Server ..............................  3
     4.1   Obtaining a SIP or SIPS URI with comp=sigcomp ........  4
5.   Sending a Response to a Client .............................  5
6.   Double Record-Routing ......................................  6
7.   Error Situations ...........................................  6
8.   Augmented BNF ..............................................  7
9.   Example ....................................................  7
10.  Security Considerations .................................... 10
11.  IANA Considerations ........................................ 10
12.  Acknowledgements............................................ 10
13.  Normative References ....................................... 10
14.  Informative References ..................................... 11
15.  Author's Address............................................ 11
16.  Full Copyright Statement.................................... 12

Status of This Memo πŸ“œ

This doc is an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements 🌸 For where this protocol stands in standardization, check the current edition of the "Internet Official Protocol Standards" (STD 1) ✨ Distribution of this memo is unlimited πŸ’œ

Copyright (C) The Internet Society (2003).  All Rights Reserved.

Abstract 🌈

Here's the vibe: this doc describes a way to signal that compression is wanted for one or more Session Initiation Protocol (SIP) messages πŸ¦‹ It also says when it's appropriate to send compressed SIP messages to a SIP entity πŸ’…

1. Introduction ✨

Let's set the scene πŸŽ€ A SIP [1] client sending a request to a SIP server usually does a DNS lookup for the server's domain name πŸ‘€ If NAPTR [4] or SRV [5] records exist for that server, the client can say which service it wants 🫢 Here, "service" means the transport protocol SIP should use, like UDP, TCP or SCTP πŸ”₯ A SIP server that supports, say, three different transport protocols ends up with three different DNS entries πŸ’€

Now, the number of transport protocols an application layer protocol supports isn't expected to explode anytime soon, so one DNS entry per transport seems like a scalable enough plan πŸ“

BUT, sometimes you need to slot new layers in between the transport protocol and the application layer protocol 😭 Examples are transport layer security and compression 🧚 If DNS were used to figure out which of these layers a server offers, the number of DNS entries that server needs would grow super fast πŸ’€

Picture a server that supports TCP and SCTP as transports, TLS for transport security, and SigComp for signaling compression. It would need these 8 DNS entries:

  1. TCP, no security, no compression
  2. TCP, no security, SigComp
  3. TCP, TLS, no compression
  4. TCP, TLS, SigComp
  5. SCTP, no security, no compression
  6. SCTP, no security, SigComp
  7. SCTP, TLS, no compression
  8. SCTP, TLS, SigComp

Yeah, that's giving "not scalable" πŸ™ˆ So the doc says we need an application layer mechanism to express support for signaling compression πŸ’…

Quick aside: for historical reasons, both HTTP and SIP use a different port for TLS on top of TCP than they do for TCP alone. At present, though, that solution isn't considered scalable anymore πŸ₯Ί

A SIP element that supports compression has to be ready to receive both compressed and uncompressed messages on the same port πŸ‘‘ It tells them apart by the cookie in the topmost bits of every compressed message, which is how it demultiplexes them πŸ”₯

2. Overview of operation πŸ¦‹

There are two types of SIP messages: SIP requests and SIP responses πŸ’– Clients send SIP requests to the host part of a URI, and servers send responses to the host in the sent-by parameter of the Via header field πŸ‘€

The doc defines two parameters, one for SIP URIs and one for the Via header field πŸŽ€ Both parameters have the same format, as you can see in these examples:

sip:alice@atlanta.com;comp=sigcomp
Via: SIP/2.0/UDP server1.foo.com:5060;branch=z9hG4bK87a7;comp=sigcomp

If comp=sigcomp shows up in a URI, the request has to be compressed using SigComp, as defined in [2] πŸ’… If comp=sigcomp shows up in a Via header field, the response has to be compressed using SigComp 🫢

So, basically, comp=sigcomp tells you that the SIP entity behind that URI or Via header field supports SigComp and is willing to receive compressed messages 🌈 And here's the cute part: having comp=sigcomp mean both "willingness" AND "support" lets the receiver of a SIP message influence whether SigComp gets used at a given time 🧚

3. SigComp implementations for SIP πŸ’œ

Every SIP implementation that supports SigComp MUST implement the procedures described in this document. πŸ”₯

4. Sending a Request to a Server πŸš€

A request gets sent to the host part of a URI πŸ‘€ This URI is called the next-hop URI, and it's either the Request-URI of the request or an entry in the Route header field 🫢

  • If the next-hop URI contains the parameter comp=sigcomp, the client SHOULD compress the request using SigComp, as defined in [2] ✨
  • If the next-hop URI is a SIPS URI, the request SHOULD be compressed before it is passed to the TLS layer πŸ”’
  • A client MUST NOT send a compressed request to a server if it does not know whether or not the server supports SigComp πŸ™…β€β™€οΈ

Whether or not the request is sent compressed, if a client wants to receive subsequent requests in the same dialog compressed in the UAS->UAC direction, this client SHOULD add the parameter comp=sigcomp to the URI in the Contact header field, as long as it's a user agent client πŸ¦‹ If the client is a proxy, it SHOULD add the parameter comp=sigcomp to its URI in the Record-Route header field πŸ’…

Next, if a user agent client sends a compressed request, it SHOULD add the parameter comp=sigcomp to the URI in the Contact header field 🌸 And if a proxy that Record-Routes sends a compressed request, it SHOULD add comp=sigcomp to its URI in the Record-Route header field πŸ’–

If a client sends a compressed request, it SHOULD add the parameter comp=sigcomp to the topmost entry of the Via header field πŸŽ€

Last one in this section: if a client doesn't know whether the server supports SigComp, but in case it does, the client would still like to receive compressed responses, this client SHOULD add the parameter comp=sigcomp to the topmost entry of the Via header field 🧚 The request itself, as stated above, will not be compressed πŸ™ƒ

4.1. Obtaining a SIP or SIPS URI with comp=sigcomp πŸ”‘

For requests inside a dialog, a next-hop URI with the comp=sigcomp parameter comes from a Record-Route header field when the dialog is established 🫢 A client sending a request outside a dialog can also get SIP URIs with comp=sigcomp from a Contact header field in a 3xx or 485 response to that request πŸ’«

Now, clients setting up a session usually won't want to wait until the dialog is established before they start compressing messages 😭 One of the biggest wins SigComp can bring to SIP is compressing the initial INVITE of a dialog, while the user is waiting for the session to be established ✨ So clients need a way to get a comp=sigcomp URI from their outbound proxy before the user decides to set up a session πŸš€

One option is manual configuration πŸŽ€ But sometimes clients need to be configured automatically πŸ‘€ Sadly, current mechanisms for SIP client configuration (for example, using DHCP [6]) don't let you give the client URI parameters πŸ’€ So in this case, the client SHOULD send an uncompressed OPTIONS request to its outbound proxy 🫢 The outbound proxy can provide an alternative SIP URI with the comp=sigcomp parameter in a Contact header field in a 200 OK response to that OPTIONS request 🧚 The client can then use this URI for subsequent requests sent through the same outbound proxy, using compression πŸ¦‹

RFC 3261 [1] doesn't define how a proxy should respond to an OPTIONS request addressed to itself πŸ™ˆ It only describes how servers respond to OPTIONS addressed to a particular user. Section 11.2 of RFC 3261 says:

Contact header fields MAY be present in a 200 (OK) response and
have the same semantics as in a 3xx response.  That is, they may
list a set of alternative names and methods of reaching the user.

This doc extends that behavior to proxy servers responding to OPTIONS addressed to them πŸ’… They MAY list a set of alternative URIs to contact the proxy 🌈

Also, receiving incoming requests compressed (even initial INVITEs) isn't a problem πŸ™Œ That's because user agents can REGISTER a SIP URI with comp=sigcomp in their registrar, and then all incoming requests for the user get sent to that SIP URI using compression πŸ’–

5. Sending a Response to a Client πŸ“¨

A response gets sent to the host in the sent-by parameter of the Via header field πŸŽ€ If the topmost Via header field contains the parameter comp=sigcomp, the response SHOULD be compressed πŸ’… Otherwise, the response MUST NOT be compressed πŸ™…β€β™€οΈ

Here's where it gets spicy 🌢️ To avoid asymmetric compression (that's when two SIP entities exchange compressed requests in one direction and uncompressed requests in the other), proxies need to rewrite their Record-Route entries in the responses πŸ”₯ A proxy doing Record-Route inspects the Record-Route header field in the response and the Contact header field in the request that triggered that response (there's an example of this in Section 9) πŸ‘€ It looks for the URI of the next upstream hop (the one closer to the user agent client) in the route set 🫢 If that URI contains the parameter comp=sigcomp, the proxy SHOULD add comp=sigcomp to its entry in the Record-Route header field ✨ If that URI does NOT contain comp=sigcomp, the proxy SHOULD remove comp=sigcomp (if it's there) from its entry in the Record-Route header field 🧚

Same energy for the user agent server: it SHOULD add comp=sigcomp to the Contact header field of the response if the URI of the next upstream hop in the route set contained the parameter comp=sigcomp πŸ¦‹

Reminder: "does NOT" above is just a plain-English emphasis word. The actual rules are the lowercase text in the doc, so nothing's changed πŸ™ˆ

6. Double Record-Routing πŸͺž

Proxies usually add zero or one Record-Route entries to a particular request, but some proxies add two of them to avoid rewriting Record-Route πŸ’« A classic example is a SIP proxy that acts as a firewall between two networks πŸ”₯ Depending on which network a request comes from, the proxy receives it on a different interface 🌸 The proxy adds one Record-Route entry for one interface and a second one for the other interface πŸ’– This way, the proxy doesn't need to rewrite the Record-Route header field on the response πŸ‘‘

Proxies that receive compressed messages from one side of the dialog (e.g., upstream) and uncompressed messages from the other side (e.g., downstream) MAY use the mechanism described above. πŸ¦‹

If a proxy detects that the next-hop proxy for a request is the proxy itself and that the request will not be sent through the network, the proxy MAY choose not to compress the request even if the URI contains the comp=sigcomp parameter. πŸ’…

7. Error Situations ✨

okay so, if a compressed SIP request lands on a SIP server that doesn't understand SigComp, the server literally has no way to tell the client something went wrong 😭. The message is impossible to parse, and there's no Via header field pointing to an address where an error response could go. Total ghosting, bestie πŸ’€.

If a SIP client sends a compressed request and the client transaction times out without having received any response, the client SHOULD retry the same request without using compression. If the compressed request was sent over a TCP connection, the client SHOULD close that connection and open a new one to send the uncompressed request. Otherwise the server would not be able to detect the beginning of the new message. It's all about knowing where the new message starts, periodt πŸŽ€.

8. Augmented BNF

This section provides the augmented Backus-Naur Form (BNF) of both parameters described above. 🧚

The compression URI parameter is a "uri-parameter", as defined by the SIP ABNF (Section 25.1 of [1]):

   compression-param  =  "comp=" ("sigcomp" / other-compression)
   other-compression  =  token

The Via compression parameter is a "via-extension", as defined by the SIP ABNF (Section 25.1 of [1]):

   via-compression    =  "comp" EQUAL ("sigcomp" / other-compression)
   other-compression  =  token

9. Example

The following example illustrates the use of the parameters defined above. The call flow of Figure 1 shows an INVITE-200 OK-ACK handshake between a UAC and a UAS through two proxies. Proxy P1 does not Record-Route but proxy P2 does. Both proxies support compression, but they do not use it by default. 🌸

   UAC            P1            P2           UAS

    |(1)INVITE(c) |             |             |
    |------------>| (2) INVITE  |             |
    |             |------------>| (3) INVITE  |
    |             |             |------------>|
    |             |             | (4) 200 OK  |
    |             | (5) 200 OK  |<------------|
    |(6)200 OK(c) |<------------|             |
    |<------------|             |             |
    |             |  (7)ACK(c)  |             |
    |-------------------------->|   (8) ACK   |
    |             |             |------------>|
    |             |             |             |
    |             |             |             |

Figure 1: INVITE transaction through two proxies

Messages (1), (6) and (7) are compressed (c).

We provide a partial description of the messages involved in this call flow below. Only some parts of each message are shown, namely the Method name, the Request-URI and the Via, Route, Record-Route and Contact header fields. We have not used a correct format for these header fields. We have rather focus on the contents of the header fields and on the presence (or absence) of the "comp=sigcomp" parameter. πŸŽ€

   (1) INVITE UAS
       Via: UAC;comp=sigcomp
       Route: P1;comp=sigcomp
       Contact: UAC;comp=sigcomp

P1 is the outbound proxy of the UAC, and it supports SigComp. The UAC is configured to send compressed traffic to P1, and therefore, it compresses the INVITE (1). In addition, the UAC wants to receive future requests and responses for this dialog compressed. Therefore, it adds the comp=Sigcomp parameter to the Via and to the Contact header fields. πŸ’–

   (2) INVITE UAS
       Via: P1
       Via: UAC;comp=sigcomp
       Route: P2
       Contact: UAC;comp=sigcomp

P1 forwards the INVITE (2) to P2. P1 does not use compression by default, so it sends the INVITE uncompressed to P2. πŸ“

   (3) INVITE UAS
       Via: P2
       Via: P1
       Via: UAC;comp=sigcomp
       Record-Route: P2
       Contact: UAC;comp=sigcomp

P2 forwards the INVITE (3) to the UAS. P2 supports compression, but it does not use it by default. Therefore, it sends the INVITE uncompressed. P2 wishes to remain in the signalling path and therefore it Record-Routes. πŸ‘‘

   (4) 200 OK
       Via: P2
       Via: P1
       Via: UAC;comp=sigcomp
       Record-Route: P2
       Contact: UAS

The UAS generates a 200 OK response and sends it to the host in the topmost Via, which is P2. ✨

   (5) 200 OK
       Via: P1
       Via: UAC;comp=sigcomp
       Record-Route: P2;comp=sigcomp
       Contact: UAS

P2 receives the 200 OK response. P2 Record-Routed, so it inspects the Route set for this dialog. For requests from the UAS towards the UAC (the opposite direction than the first INVITE), the next hop will be the Contact header field of the INVITE, because P1 did not Record-Route. That Contact identified the UAC:

      Contact: UAC;comp=sigcomp

Since the UAC wants to receive compressed requests (Contact of the INVITE), P2 assumes that the UAC would also like to send compressed requests (Record-Route of the 200 OK). Therefore, P2 modifies its entry in the Record-Route header field of the 200 OK (5). In the INVITE (3), P2 did not used the comp=sigcomp parameter. Now it adds it in the 200 OK (5). This will allow the UAC sending compressed requests within this dialog. 🧠

   (6) 200 OK
       Via: UAC;comp=sigcomp
       Record-Route: P2;comp=sigcomp
       Contact: UAS

P1 sends the 200 OK (6) compressed to the UAC because the Via header field contained the comp=sigcomp parameter. πŸ¦‹

   (7) ACK UAS
       Via: UAC;comp=sigcomp
       Route: P2;comp=sigcomp
       Contact: UAC;comp=sigcomp

The UAC sends the ACK (7) compressed directly to P2 (P1 did not Record-Route). 🌈

   (8) ACK UAS
       Via: P2
       Via: UAC;comp=sigcomp
       Contact: UAC;comp=sigcomp

P2 sends the ACK (8) uncompressed to the UAS. And that's the whole call flow, bestie 🫢.

10. Security Considerations

A SIP entity receiving a compressed message has to decompress it and to parse it. This requires slightly more processing power than only parsing a message. This implies that a denial of service attack using compressed messages would be slightly worse than an attack with uncompressed messages. 😭

An attacker inserting the parameter comp=sigcomp in a SIP message could make a SIP entity send compressed messages to another SIP entity that did not support SigComp. Appropriate integrity mechanisms should be used to avoid this attack. πŸ”₯

11. IANA Considerations

This document defines the "comp" uri-parameter and via-extension. New values for "comp" are registered by the IANA at http://www.iana.org/assignments/sip-parameters when new signalling compression schemes are published in standards track RFCs. The IANA Considerations section of the RFC MUST include the following information, which appears in the IANA registry along with the RFC number of the publication. πŸ“‹

  • Name of the compression scheme.
  • Token value to be used. The token MAY be of any length, but SHOULD be no more than ten characters long.

The only entry in the registry for the time being is: 🌸

   Compression scheme      Token      Reference
   ---------------------   ---------  ---------
   Signaling Compression   sigcomp    RFC 3486

12. Acknowledgements

Allison Mankin, Jonathan Rosenberg and Miguel Angel Garcia-Martin provided valuable comments on this memo. 🫢

13. Normative References

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

[2] Price, R., Bormann, C., Christoffersson, J., Hannu, H., Liu, Z. and J. Rosenberg, "Signaling Compression (SigComp)", RFC 3320, January 2003.

[3] Bradner, S., "Key words for use in RFCs to indicate requirement levels", BCP 14, RFC 2119, March 1997.

14. Informative References

[4] Mealling, M., "Dynamic Delegation Discovery System (DDDS) Part Three: The Domain Name System (DNS) Database", RFC 3403, October 2002.

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

[6] Schulzrinne, H., "DHCP option for SIP servers", Work in Progress.

15. Author's Address ✨

Gonzalo Camarillo Ericsson Advanced Signalling Research Lab. FIN-02420 Jorvas Finland

EMail: Gonzalo.Camarillo@ericsson.com

Copyright (C) The Internet Society (2003). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement πŸ’œ

Funding for the RFC Editor function is currently provided by the Internet Society. πŸŽ€

πŸ“¦ where this page comes from