背景
compression
模块用于对 SIP 消息进行压缩,以减少网络传输量。
相比于上一章kamailio
, opensips
不仅可以压缩body
,还能压缩header
和调整压缩率,使用上更灵活。
依赖外部模块:zlib
。
官方文档地址: compression模块
本次测试的opensips版本信息为:
version: opensips 3.5.5 (x86_64/linux)
重要参数解析
1
2
|
# 压缩等级1-9, 默认是6,等级越高,压缩耗时越长.
modparam("compression", "compression_level", 6)
|
官方文档写的是: modparam("mc", "mc_level", "3")
,这个是错的,已提issue
修正。
重要函数
mc_compress([algo], flags, [whitelist])
压缩当前的SIP消息
algo
压缩算法, 可选值为0(deflate)
, 1(gzip)
flags
压缩参数,设置压缩的范围
b
压缩body
,如果没有body
,则不压缩
h
压缩所有header
,除了白名单中的
s
header
和body
可以分开压缩,将创建新的Comp-Hdrs
头存储压缩后的header
e
指定base64编码
whitelist
不压缩的白名单, 头可以使用"|“分隔。
mc_compact([whitelist], flags)
flags
: ’n’不使用缩短名, 此函数有四种功能:
- 没有在白名单中的
header
会被移除
- 相同类型的
header
会合并,使用”,“分隔
- 有短名的
header
会变成缩短名
sdp
中小于96
的rtpmap
会被移除。
mc_decompress()
进行base64解码和gzip/deflate解压, 只能被用在REQUEST_ROUTE
,LOCAL_ROUTE
,FAILURE_ROUTE
上.
实战
配置示例
整体配置使用opensips-基础代理设置
章节的配置, 并添加如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
loadmodule "compression.so"
...
route {
...
if ($si != "172.16.4.114") {
$du = "sip:172.16.4.114:5060";
$socket_out="udp:172.16.4.111:5260";
}
if (!mc_compress(0, "b")) {
xlog("L_DBG","[$cfg_line][$ci]---main--: compress failed.\n");
}
# # do lookup with method filtering
# if (!lookup("location","method-filtering")) {
# t_newtran();
# t_reply(404, "Not Found");
# exit;
# }
route(relay);
}
|
在发送INVITE
时, 设置mc_compress(0, "b")
。
测试
测试的sip
信令图为:

mc_compress
关于flags
参数,
s
只有和bh
一起使用,才有效果,即:bhs
。 此时消息体为:

新增了Comp-Hdrs
,Headers-Encoding
。
h
,e
: 单独用没有任何效果.
b
: 压缩body
,此时消息体为:

目前发送给freeswitch
报错400 Bad Session Description
:

已提交issue
, 和kamailio
对比了一下源码,虽然都是zlib
库,但是kamailio
用的是compress函数
1
2
3
4
5
6
|
ret = compress(
(unsigned char *)nbody.s, &nlen, (unsigned char *)obody.s, olen);
if(ret != Z_OK) {
LM_ERR("error compressing body (%d)\n", ret);
goto done;
}
|
opensips
用的是compress2函数
:
1
2
3
4
5
|
rc = compress2((unsigned char*)bufcompressed.s,
&temp,
(unsigned char*)buf2compress.s,
(unsigned long)buf2compress.len,
mc_level);
|
be
: 以base64
展示压缩后的body
, 此时消息体为:

发送给freeswitch
报错415 Unsupported Media Type
:

说明freeswitch
不支持这样的压缩方式。
mc_compact
把上面的mc_compress(0,"b")
换成mc_compact()
。
原始的INVITE
的数据为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
2025/08/13 13:53:16.834540 172.16.4.111:5260 -> 172.16.4.114:5060
INVITE sip:1008@172.16.4.111:5261 SIP/2.0
Record-Route: <sip:172.16.4.111:5260;lr>
Via: SIP/2.0/UDP 172.16.4.111:5260;branch=z9hG4bK072a.b15e8867.0
Via: SIP/2.0/UDP 172.16.80.13:58807;received=172.16.80.13;rport=58807;branch=z9hG4bKPjf13de5761ca54d1895886f961b23ff64
Max-Forwards: 69
From: <sip:1005@172.16.4.111>;tag=9769c9c2b927412aaecd915eec7b1fb1
To: <sip:1008@172.16.4.111>
Contact: <sip:1005@172.16.80.13:58807;ob>
Call-ID: 970d5f96986b4b2aa5fa069dba9e2948
CSeq: 3216 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, norefersub
User-Agent: MicroSIP/3.21.6
Content-Type: application/sdp
Content-Length: 321
v=0
o=- 3964082099 3964082099 IN IP4 172.16.4.111
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 30988 RTP/AVP 8 0 101
c=IN IP4 172.16.4.111
b=TIAS:64000
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ssrc:580466598 cname:31a747bc699122c1
a=sendrecv
a=rtcp:30989
|
使用mc_compact()
后的INVITE
数据为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
2025/08/13 13:46:24.616445 172.16.4.111:5260 -> 172.16.4.114:5060
INVITE sip:1008@172.16.4.111:5261 SIP/2.0
v: SIP/2.0/UDP 172.16.4.111:5260;branch=z9hG4bKf914.0b281385.0, SIP/2.0/UDP 172.16.80.13:58807;received=172.16.80.13;rport=58807;
anch=z9hG4bKPj07898ec3e16c4350843b1a4de4a89ceb
t: <sip:1008@172.16.4.111>
f: <sip:1005@172.16.4.111>;tag=2b204cd2db594ce0bca55e8e525a1c14
CSeq: 6255 INVITE
i: 9a37bdb33bb7418d9b6e5c088c8312af
m: <sip:1005@172.16.80.13:58807;ob>
Record-Route: <sip:172.16.4.111:5260;lr>
c: application/sdp
l: 278
v=0
o=- 3964081686 3964081686 IN IP4 172.16.4.111
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 31614 RTP/AVP 8 0 101
c=IN IP4 172.16.4.111
b=TIAS:64000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ssrc:1957038347 cname:2c067dcd05730c02
a=sendrecv
a=rtcp:31615
|
可以看到在opensips
转发INVITE
时,Via
,From
,To
,Call-id
,Contact
等都被换成了缩略参数,
并且sdp
中的rtpmap:PCMU/PCMA
删除了.
在freeswitch
往opensips
发送183
,200OK
时,也带了缩略参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
2025/08/13 13:46:25.451770 172.16.4.114:5060 -> 172.16.4.111:5260
SIP/2.0 183 Session Progress
v: SIP/2.0/UDP 172.16.4.111:5260;branch=z9hG4bKf914.0b281385.0, SIP/2.0/UDP 172.16.80.13:58807;received=172.16.80.13;rport=58807;
anch=z9hG4bKPj07898ec3e16c4350843b1a4de4a89ceb
Record-Route: <sip:172.16.4.111:5260;lr>
f: <sip:1005@172.16.4.111>;tag=2b204cd2db594ce0bca55e8e525a1c14
To: <sip:1008@172.16.4.111>;tag=tZ2epK6U1Dtae
i: 9a37bdb33bb7418d9b6e5c088c8312af
CSeq: 6255 INVITE
Contact: <sip:1008@172.16.4.114:5060;transport=udp>
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release+git~20230615T110520Z~4ce1b74880~64bit
Accept: application/sdp
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, presence, as-feature-event, dialog, line-seize, call-info, sla, include-session-description
presence.winfo, message-summary, refer
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 254
Remote-Party-ID: "1008" <sip:1008@172.16.4.111>;party=calling;privacy=off;screen=no
v=0
o=FreeSWITCH 1755033712 1755033713 IN IP4 172.16.4.114
s=FreeSWITCH
c=IN IP4 172.16.4.114
t=0 0
m=audio 30016 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=rtcp:30017 IN IP4 172.16.4.114
|
可以看到From
,To
, Via
还是之前的缩略参数,其他的header
参数被恢复了.
总结
- 虽然
opensips
说可以压缩Header
,但是实际测试过程中,并未生效此功能,但是缩略Header
参数功能Ok.
opensips
的压缩body
, 确实是压缩了,但是压缩后的body
,freeswitch
并不能解析.应该是有问题的。
分别对比kamailio
和opensips
的压缩body
功能抓包,发现kamailio
的消息体能够被tcpdump
正确解析,
但是opensips
的消息体被tcpdump
解析失败.
kamailio
的压缩body
功能抓包:

opensips
的压缩body
功能抓包:
