一种基于Go语言的SIP协议栈设计与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
设计应用技术
语言的SIP协议栈设计与实现
邓杨凡
(中国电子科技集团公司第三十研究所,四川
会话发起协议(Session Initiation Protocol,SIP)是由互联网工程任务组(Internet Engineering Task Force,
它是一个基于文本的应用层控制协议,能够创建、
下一代网络(Next Generation Network,
Multimedia Subsystem,IMS)等网络,支持语音、视频、数据等多媒体业务。
基于
协议栈,具备作为客户端并发发起或处理多路呼叫的能力。
会话发起协议(SIP);客户端;Go语言;多媒体通信
Design and Implementation of a SIP Protocol Stack Based on Go Language
DENG Yangfan
Institute of CETC, Chengdu 610041
Abstract: Session Initiation Protocol (SIP) is a multimedia communication protocol formulated by the Internet Engineering Task Force (IETF). It is a text-based application layer control protocol, which can create, modify and
实体都是事务用户。
当一个事务用户希望发送请求时,就创建一个客服端事
字符集。
种类型,请求消息和响
规定的通用消息格式,包括起始行、一个或多个消息头、一个空行以及一个可选消息体。
和状态行(
的起始行,状态行是响应消息的起始行。
请求消息包含请求行、消息头、空行以及消息体,响应消息包括状态行、消息头、空行以及消息体。
6种请求消息如表
表1 SIP请求消息
功能说明
向SIP服务器注册
用于建立用户代理之间的媒体会话
用于终止已建立的会话,可以由主叫或者被叫方发送
用于查询的用户代理或围绕其功能的代理服务器,并发现其当前的可用性
用于确认最后响应的
用于终止未建立会话
响应消息的第一行由状态码构成,表示服务信令和实时传输协议(
一套多级流水线的文本消息处理流程。
第1级以空行为分割符,将消息分割为消息头(Message Header)
和消息体(Message Body)。
第2级解析消息头与消息体中的回车换行符,以此标志作为分割符,将消息分割为多条字段。
第3级以“:”作为分割符,获取字段名称。
第4级以“:”“@”等标志作为分割符,过滤出字段的参数值。
4级流水线结构的解码模型如图5所示。
针对SIP(包含SDP和RTP)的编码可以看作解析的逆向过程,编码模块根据接收消息的内容,结合当前网络状态,按照SIP消息的标准生成消息头和消息体,组合成相应的载荷。
文章设计的协议栈支持INVITE、BYE、RING以及ACK等多种消息的生成和解析,其消息编解码模块根据消息头判断消息类型,同时采用多级流水的模式进行解析。
实现上述编解码时,接收消息为16进制的数组,此时使用Go语言原生包“bytes”中的“splite”函数,利用“0x0d,0x0a”作为分割关键数组,将收到的消息进行分割,分割后的消息为一段包含关键字的字符串。
此外,分割后第一段为消息类型或“Status Line”的值。
获取到接收消息的类型后,调用相应的函数对相关消息进行解析,获取消息中“Call-ID”“From”“To”等关键参数的值进行处理存储。
消息编码利用SIP协议文本性质的特点,采用关键字填充模式进行消息组包,通过对关键字的填充来生成消息载荷。
SIP消息组包的典型编程实现如图6所示。
收到SIP 数据包
解析SIP消息合法SIP消息
错误处理
发送至
事务层处理
事务
找到匹配
确定消息
匹配事务
请求或响应
事务层处理
回复响应
创建新事务
并处理
是
否
是
否
请求
响应
图3 消息传输流程
UAC UAS
100 Trying
180 Ring
①Invite(rtp port)
ACK
②200 OK Invite(rtp port)图4 UDP传输典型流程
SIP数据报
(包含SDP)
SIP数据报
INVITE..
SDP数据报
Session ..
SIP字段
INVITE
Ring..
SDP字段
V:0O:
xx
SIP参数
From:
To:..
SDP参数
Media Attribute
Time..
图5 4级流水线结构的解码模型
· 33 ·
· 34 ·
图6 SIP 消息组包的编码实现
2.3 数据处理与数据存储模块
数据处理模块接收编解码模块解析的数据并对其进行处理,以供编解码模块生成响应消息时使用。
数据处理器根据编解码模块解析出的消息类型,调用对应的处理函数对对方支持的媒体格式和本协议栈支持的媒体格式进行对比处理,选择其中的交集作为对端通信的媒体格式。
SIP 消息通过文本形式进行信息交互,收发双方每次交付都会产生大量参数,其中大部分参数在整个会话过程中都要使用。
在支持多线程的情况下,相关参数的存储量大幅增加,这就要求协议栈能够实时创建一个存储空间来存储上述数据,同时相关函数可以方便地对其访问[4]。
结合Go 语言的特点,会话中的数据采用结构体的形式进行存储。
通过HashMap 的形式,采用一次会话中的唯一值“Call-ID ”作为键值进行检索。
会话开始时创建一条索引关系,会话结束或者会话中止时则删除。
中间可采用指针形式对索引中的值进行修改。
数据存储模块除了存储一次会话中的SIP 参数信息,还存储一次SIP 会话中的会话状态信息。
状态
信息采用同时加入部分自定义状态。
例如,协议栈作为客服端发送INVITE 同时设置一个计时器,消息的响应消息)。
数据处理存储采用言提供了“且线程安全的索引内容以结构体的形式存在。
存储呼叫信息的结构体如图77 存储呼叫信息的结构体
存储数据的结构体采用值类型的形式进行更新,每收到一条消息,就执行一次判断。
如果当前消息不”,就提取“Call-ID ”值,并同步更新上述列表;如果收到的消息为log ,并删除当前消息“有限状态机是整个协议栈的控制核心,该模块提供对协议栈运行的总体调度能力存储模块中存储的“Status ”作为状态转换的状态值,通过一次会话中的唯一键值“Call ID 的“Status Code ”或关等)作为状态变换的更新。
典型的有限状态机所示。
START
WAITING
Trying
OK
ACK
BYE
启动系统
无请求
会话发起
收到100 Trying
接受会话
收到OK
收到180 Ringing
发起BYE
收到BYE
拒绝会话
开始会话
图8 有限状态机结构
有限状态机的初始状态为WAITING,若无主叫请求或收到被叫请求,则保持此状态。
此时根据主动发出会话请求和收到会话请求,状态机会有2种状态走向。
若由SIP协议栈发起会话,则状态机由WAITING 转为INVITE,并开启一个定时器。
若在一定时间内没有收到响应消息,则重新跳转至WAITING状态,并抛出一个异常记录;若在一定时间内收到“100 Trying”回复,则进入下一个状态,等待被叫方回复“180 Ring”响应消息;若收到“180 Ring”消息后,状态机转为RINGING状态并等待200 OK消息,状态机转为ACK状态并向对端发送“ACK”响应,同时打开会话并启动RTP多媒体传输;若收不到相应的响应,则重新转到WAITING状态,重新等待会话开始。
若协议栈收到会话请求时,状态机由WAITING 转为RINGING。
此时协议栈开启定时机制,等待用户接收或中止该请求。
若目标用户接受请求,则将状态机置为OK状态,回复“200 OK”响应,等待对方最终请求为ACK后,状态机由OK状态转换为ACK,开启会话和RTP媒体传输;若用户放弃该请求,则将状态重置为WAITING状态,等待新的呼叫。
终止会话时,请求方或响应方发送BYE请求,等待200 OK消息,此时将状态机由ACK置为BYE 状态。
当一方接受BYE请求后,状态机重新复位到WAITING状态,同时发送200 OK响应并释放会话,此时一个会话结束。
3 实验验证
采用端到端的形式模拟一次SIP呼叫与语音通话过程,利用虚拟机搭建服务端与客户端。
服务端系统采用Linphone,客户端采用文章设计的协议栈系统,读取已经生成的WAV文件作为传输话音。
实验简易部署结构如图9所示。
IP地址:192.168.46.147
号码:22222222222
SIP客户端
IP地址:192.168.46.142
号码:11111111111
LinPhone
图9 实验简易部署结构
图9中,主叫端为基于SIP协议栈开发的SIP客户端软件,其IP地址为“192.168.46.147”,分配的主叫号码为“22222222222”;被叫端采用Linphone 软件,其IP地址为“192.168.46.142”,分配的被叫号码为“11111111111”。
实验中SIP信令抓包结果如图10所示。
由图10可知,基于SIP协议栈开发的SIP客户端成功发起并处理了一次呼叫的全部信令流程。
本次呼叫中传输的RTP数据流如图11所示。
图10 实验中SIP信令抓包结果图11 实验中传输的RTP数据流
4 结 论
文章基于Go语言设计并实现了一种轻型的SIP 协议栈,在跨平台部署时无须安装各种编译器和库文件,应用简单便捷。
通过在目标主机上进行实验验证,该协议栈具备主动发起呼叫并处理相关RTP媒体流的能力,具有较好的应用价值。
参考文献:
[1] IVOV E.SIP:session initiation protocol[J].Encyclopedia
of Internet Technologies & Applications,2002,58
(2):1869-1877.[2] 王彦恺.多媒体调度场景下基于SIP的全双工语
音通信[D].南京:东南大学,2018.
[3] 侯兴林.面向融合通信系统的SIP协议栈的设计
与实现[D].北京:北京邮电大学,2016.
[4] 丁 曼,张代远.一种SIP协议栈中呼叫过程的
设计与实现[J].中国新通信,2010,12(21):43-46.
[5] SINGH A,MAHADEVAN P,ACHARYA A,
et al.Design and implementation of SIP network and client services[C]//Computer Communications and Networks,2004.
· 35 ·。