Featured image of post opensips compression模块

opensips compression模块

背景

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 headerbody可以分开压缩,将创建新的Comp-Hdrs头存储压缩后的header
    • e 指定base64编码
  • whitelist 不压缩的白名单, 头可以使用"|“分隔。

mc_compact([whitelist], flags)

flags: ’n’不使用缩短名, 此函数有四种功能:

  1. 没有在白名单中的header会被移除
  2. 相同类型的header会合并,使用”,“分隔
  3. 有短名的header会变成缩短名
  4. sdp中小于96rtpmap会被移除。

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参数,

  1. s只有和bh一起使用,才有效果,即:bhs。 此时消息体为: invite

新增了Comp-Hdrs,Headers-Encoding

  1. h,e: 单独用没有任何效果.
  2. b: 压缩body,此时消息体为: invite

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

已提交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);
  1. be: 以base64展示压缩后的body, 此时消息体为: invite

发送给freeswitch报错415 Unsupported Media Type: invite

说明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删除了.

freeswitchopensips发送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参数被恢复了.

总结

  1. 虽然opensips说可以压缩Header,但是实际测试过程中,并未生效此功能,但是缩略Header参数功能Ok.
  2. opensips的压缩body, 确实是压缩了,但是压缩后的body,freeswitch并不能解析.应该是有问题的。 分别对比kamailioopensips的压缩body功能抓包,发现kamailio的消息体能够被tcpdump正确解析, 但是opensips的消息体被tcpdump解析失败.

kamailio的压缩body功能抓包: tcpdump

opensips的压缩body功能抓包: tcpdump

本博客已稳定运行
发表了57篇文章 · 总计94.35k字
本站总访问量 次 · 您是本站第 位访问者
粤ICP备2025368587号-1| 使用 Hugo 构建
主题 StackJimmy 设计