飞信分析之五:用即时消息聊天时的协议交互过程

来源:互联网 发布:php 图片上传预览插件 编辑:程序博客网 时间:2024/04/30 02:17

http://hi.baidu.com/nathan2007/blog/item/1ee3823422ebbdb6d1a2d376.html

 

飞信分析之五:用即时消息聊天时的协议交互过程
2007年03月18日 23:17作者:nathan

以下分析基于Fetion 2006 beta 2.1.0.0,其SIP-C协议的版本是2.0。

前面列出了飞信的SIP-C协议支持的所有SIP Method以及Header Field,下面就两个用户间的聊天,即互相发送文本消息来看看飞信通过SIP-C协议的工作过程。


先看看RFC规定的SIP的建立会话的标准过程,在RFC3261中通过SIP建立会话的过程是这样子的:

atlanta.com . . . biloxi.com
. proxy proxy .
. .
Alice's . . . . . . . . . . . . . . . . . . . . Bob's
softphone SIP Phone
| | | |
| INVITE F1 | | |
|--------------->| INVITE F2 | |
| 100 Trying F3 |--------------->| INVITE F4 |
|<---------------| 100 Trying F5 |--------------->|
| |<-------------- | 180 Ringing F6 |
| | 180 Ringing F7 |<---------------|
| 180 Ringing F8 |<---------------| 200 OK F9 |
|<---------------| 200 OK F10 |<---------------|
| 200 OK F11 |<---------------| |
|<---------------| | |
| ACK F12 |
|------------------------------------------------->|
| Media Session |
|<================================================>|
| BYE F13 |
|<-------------------------------------------------|
| 200 OK F14 |
|------------------------------------------------->|
| |

上图中F1-F14分别是步骤的编号,而Medai Session过程在飞信中,就是文本聊天消息的传递过程了。在RFC3428中对标准SIP的扩展了一个Message方法,通过Message方法承载这种即时消息,这样,上图中的Media Session按RFC3428的规定,就是这样的:
| F1 MESSAGE | |
|--------------------> | F2 MESSAGE |
| | ----------------------->|
| | |
| | F3 200 OK |
| | <-----------------------|
| F4 200 OK | |
|<-------------------- | |
| | |
| | |
| | |
User 1 Proxy User 2

飞信是完全依照以上RFC的要求来实现这一过程来的。


下面来看飞信具体实现的聊天过程是怎么样的。假定有这么一个聊天过程是:飞信用户A(飞信号为123456789,飞信用TCP方式工作在111.111.111.111:1111)双击好友列表中的飞信用户B(飞信号为987654321,飞信用TCP方式工作在222.222.222.222:2222),这时聊天窗口弹出,用户A对B发出:"Hello!测试“,然后用户A关闭了聊天窗口,结束了这次即时消息对话过程。

我们看用户A这一端来看整个聊天过程中,用户A与服务器(SIP的Proxy Server)的交互过程是 (请对照上面RFC的SIP会话建立过程,另外,下面的红色字是表示数据的发送方向,蓝色字是全部的SIP消息,即TCP包的包体部分。):
第一步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
I fetion.com.cn SIP-C/2.0
F: 123456789
I: 16
Q: 1 I
T: sip:987654321@fetion.com.cn;p=1972
K: text/html-fragment
K: multiparty
L: 137

v=0
o=-0 0 IN 111.111.111.111:1111
s=session
c=IN IP4 111.111.111.111:1111
t=0 0
m=message 1111 sip sip:123456789@fetion.com.cn;p=xxxx

上面是发到服务器的第一条消息,是一个SIP协议的INVITE请求,发到飞信的服务器,服务器地址是221.130.45.203,端口8080,协议是TCP,上面的SIP消息就直接放在TCP的包中,UTF-8编码。

消息的第1是请求行,I=INVITE(这缩写的标准在哪里?我还没找到来依据),fetion.com.cn是请求对象(又没用标准的uri),"sIP-C/2.0"是当前的SIP-C协议版本。
第2行开始是消息头:"F"即From,标识从用户A(123456789)发出的请求(依然没用标准uri,应该是sip:123456789@xx.fetion.com.cn才对吧....);"I"即CallID,按标准的SIP的规定,这应该是一个随机产生的一个全局唯一的标识符,它应该在客户端和服务器整个交互的过程中保持不变,但在飞信的SIP-C协议中,这是一个序列号,第一次与8080端口建立连接发出第一个请求时,这个值为1,以后每次发出一个请求则加1;"Q"即CSeq,也就是Command Sequence,它由一个整数的序列号和一个SIP方法组成,SIP方法与这个消息的SIP方法相同,这个序列号在一个会话过程中每次加1,这样来标识SIP消息的顺序;"T"就是To啦,这里倒是用了标准uri的表示,"K"即Supported,表示客户端所支持扩展;"L"即Content-Length,就是消息体的长度。

从v=0开始的是消息体,用SDP(Session Description Protocol)描述的,根据RFC:
v= (protocol version),在目前飞信的INVITE中,固定的v=0
o= (owner/creator and session identifier). 在目前飞信的INVITE中,前面是固定的,后面是发起人(用户A)的IP地址和端口
s= (session name). 在目前飞信的INVITE中,固定的为s=session
c=* (connection information - not required if included in all media).在目前飞信的INVITE中,除后面的发起人(用户A)的IP地址和端口外,前面是固定的。
t= (time the session is active) 。在目前飞信的INVITE中,固定的为"t=0 0"
m= (media name and transport address)。在目前飞信的INVITE中,"1111"是发起人的TCP端口,后面的sip:xxxxxxxx,是发起人的uri。


第二步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
SIP-C/2.0 100 Trying
Q: 1 I
T: sip:987654321@fetion.com.cn;p=xxxx
I: 16

这是服务器回过来的对第一步的INVITE消息的一个RESPONSE,所以,I=16,Q=1 I。表示正在查找用户B。

第三步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
SIP-C/2.0 200 OK
Q: 1 I
K: text/html-fragment
K: multiparty
T: sip:123456789@fetion.com.cn;p=xxx
I: 16
L: 135

v=0
o=-0 0 IN 222.222.222.222:2222
s=session
c=IN IP4 222.222.222.222:2222
t=0 0
m=message 2222 sip sip:987654321@fetion.com.cn;p=xxx
这是服务器转过来的用户B对用户A的INVITE的回复,是:OK,其中222.222.222.222:2222是用户B的IP和端口。

第四步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
A fetion.com.cn SIP-C/2.0
I: 16
Q: 1 A
T: sip:987654321@fetion.com.cn;p=xxx
F: 123456789
接着,用户A发出ACK消息。

第五步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
M fetion.com.cn SIP-C/2.0
F: 123456789
I: 16
Q: 2 M
T: sip:987654321@fetion.com.cn;p=xxxx
C: text/html-fragment
K: SaveHistory
L: 121

<Font Face='Arial' Color='-16777216' Size='9'>hello! </Font><Font Face='SimSun' Color='-16777216' Size='12'>测试</Font>
这就是用户A向对方发的即时消息,内容是“hello!测试"。这里用的是SIP Message方法,消息体是XML表示的即时消息,消息头跟INVITE相似。

第六步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
SIP-C/2.0 200 OK
Q: 2 M
T: sip:123456798@fetion.com.cn;p=xxxx
I: 16
D: Mon, 01 Mar 2007 00:00:00 GMT
XI: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
这是用户B收到第五步发出的即时消息后回过来的RESPONSE,结果是OK,其中XI这个消息头域的MessageID。

第七步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
B fetion.com.cn SIP-C/2.0
F: 123456789
I: 16
Q: 3 B
T: sip:987654321@fetion.com.cn;p=xxxxx
这是用户A开始关闭聊天窗口准备结束聊天了,向用户B发出了一个BYE的SIP请求消息。

第八步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
SIP-C/2.0 200 OK
Q: 3 B
T: sip:123456789@fetion.com.cn;p=xxxx
I: 16
这是最后用户B对对用户A发出的BYE的回复。


在用户B那边,整个交互过程跟用户A这边对应,用户A在发出INVITE,要求和B会话,而用户B这边则是回应邀请。

那发短信是怎么样的呢?也基本差不多,如发一个内容为test的短信到用户B时的SIP Message请求消息是这样的:
111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
M fetion.com.cn SIP-C/2.0
F: 12345678
I: 16
Q: 1 M
T: sip:987654321@fetion.com.cn;p=xxxx
N: SendSMS
L: 4

test


以上分析都是飞信通过TCP直连方式工作时的情况,飞信通过HTTP直连呢?工作过程跟上面完全一样,不同的是,连接的是221.130.45.203:80,协议是HTTP,采用的POST请求是:
POST /ht/sd.aspx?t=s&i=2 HTTP/1.1
POST的数据分就是上面一样的SIP消息了。

飞信发送通过即时消息聊天时,整个过程就是这样子。 通过这个分析,我们也可以看到,飞信聊天时整个内容是既未加密又未变换的(MSN还作了点点变换),因此聊天过程是可以被截取的,因此通过飞信聊天是会被别人偷听的,就如同去年MSN曝出的监听事件一样。那这个问题是可以解决的吗?当然是可以的,其实扩展SIP的Message方法时,RFC中就提到这一点,我想飞信目前只是没去做,一旦这个问题暴露出来,对聊天内容进行加密,甚至是公开密钥的端到端强加密,都是可能和容易的,只不过不知道会不会不符合监管要求,呵呵:)。


补记:发现了吗?上面分析中提到的URI(在Header Field "To"中)中都带着小尾巴:p=xxxx,这里的xxxx是个数字,怎么来的呢?文中我没解释,因为我还没完全搞清楚,下回再说。


类别:飞信协议分析 | | 添加到搜藏 | 分享到i贴吧 | 浏览(10658) | 评论 (15)

上一篇:飞信分析之四:Fetion协议所支持... 下一篇:飞信分析之六:Fetion手机语聊的...

已有2人分享了这篇文章:04202009
Ta的转贴yhyqwg
Ta的转贴


最近读者:
crazybarcelonali_ying8108gaofeizhou_vipfbizeng5tmusickongbai_106singyueyang不是白小白


网友评论:
1网友:匿名网友2007年03月19日 22:09 | 回复
p=xxx好像是UAS的一个标识,另外飞信的语音呼叫流程与MSN的流程有点区别,流程图你这里贴不上来,可以看看这个地址:http://byfiles.storage.msn.com/x1pN1mp8dKYgTF4u8dHjAjEOyObcMK0SlM90v4h-l4W3Z1I0NTjkLSPxeJ2T0mys_S26s_jyM66NR5tEvVhTzXez6Jwuad-491vIhmdoylMEu0NgQVtja-Hfw 可能有误,请指正,谢谢!


2网友:匿名网友2007年03月19日 22:11 | 回复
不好意思,刚才的地址有误,这个应该可以打开:http://byfiles.storage.msn.com/x1pN1mp8dKYgTF4u8dHjAjEOyObcMK0SlM90v4h-l4W3Z1I0NTjkLSPxeJ2T0mys_S26s_jyM66NR5tEvVhTzXez6Jwuad-491vIhmdoylMEu0NgQVtja-Hfw


3网友:匿名网友2007年03月19日 22:14 | 回复
还是不行,还是给你我的blog地址吧:http://loucst.spaces.live.com/blog/cns!B6AD7C0277824A56!117.entry


4
nathan20072007年03月19日 23:33 | 回复
p=xxxx,是URI中的一个tag,关键是我不知道他是怎么计算出来的,因为我发现每个用户的这个是不变的,而且不是由客户端计算的,每次均是服务器返回的. 另外,"语音呼叫流程"你说的是手机语聊吗?你画的那个图跟飞信的实际有点点差异,一会我贴一篇关于手机语聊的SIP-C交互过程。 欢迎一起探讨。:)


5
Fetion82007年04月04日 13:47 | 回复
P=xxxx和手机号码号段有关系,我可以确定号码前面6为数字相同的p值是相同的。比如1392223xxxx和,1392224xxxx的p值是相同的。至于到底从第几位开始p值发生变化,还要有相关的号码来测试啊,没资料


6
Fetion82007年04月04日 13:51 | 回复
弄清楚号段规律之后,便可以做一个查飞信用户归属地的插件了哦,类似珊瑚虫查ip插件!不知道作者有没有兴趣?我正在想办法弄清号段p值规律,呵呵


7
Fetion82007年04月04日 14:43 | 回复
我对P值的分析,欢迎各位共同讨论 http://xinxin.name/blog/article.asp?id=102


8
nathan20072007年04月04日 16:19 | 回复
牛人啊,这个规律都被你发现了:) 用我博客上的DecodeCfg和FetionCfgEditor工具可以看Contacts.dat这个配置文件,这个文件中有所有好友的uri,其中有这个值. 我看了一下,发现确实是如此,肯定是由前6位数确定的.


9
Fetion82007年04月04日 17:18 | 回复
哈哈,今天兴奋啊


10网友:ivy2008年05月07日 11:29 | 回复
那个p应该是tag参数用来表示两端。 在to头中的tag标识发送端。 from里的标识接收端


11
cncpp2008年06月08日 18:53 | 回复
感谢!!!! 你对网络的贡献很大。


12
xiaoye_org2008年06月18日 08:53 | 回复
"以上分析都是飞信通过TCP直连方式工作时的情况,飞信通过HTTP直连呢?工作过程跟上面完全一样,不同的是,连接的是221.130.45.203:80,协议是HTTP,采用的POST请求是: POST /ht/sd.aspx?t=s&i=2 HTTP/1.1 POST的数据分就是上面一样的SIP消息了。" POST的数据如何构造呢?


13网友:houxj2008年10月12日 23:47 | 回复
IM多方通话是如何实现的? 另外,协商的TCP端口号 1111,2222没有用啊


14
xtraod2009年01月05日 09:17 | 回复
高人那,顶


15网友:匿名网友2010年03月19日 21:00 | 回复
为什么我用LZ的方法试了下,在建立了与服务器连接后,发送第一部的数据包后,服务器返回的是
rvices-version="322343230" has-offline-message="0"/><presence result="200"/></results>

原创粉丝点击