这篇文章写的还不错,基本把Skype协议的重点交互过程分析清楚了,列入本人博客用于记录参考,对于Skype协议已经研究多年,大家有什么问题也可以和我探讨。
转自:http://blog.csdn.net/collier/article/details/3671144
概要:
Skype是创建Kazaa的组织在2003年开发的一个基于Peer-to-Peer(对等网络)的VoIP客户端。它可以几乎无缝的穿越NAT和防火墙,并且语音质量比其他的VoIP客户端软件要好很多。他加密了端到端的通话,分散式存储用户信息,支持即时消息通信和网络语音会议。
本文分析了Skype的关键技术,比如登录,穿越NAT和防火墙,呼叫信令,媒体传送,编码,语音会议,并且基于三种不同网络环境下进行了分析。详细的分析了Skype网络的传输和阻断,共享列表,系统调用。此外我们还画了一幅Skype在登录时建立TCP连接的超级结点图。
普通主机(SC)
超级结点(SN)
______ 连接关系
图1 Skype网络 有三种主要的实体,普通主机、超级结点、登陆服务器。
译者注:Skype单词的由来
它是一个楚瓦什语单词...意思是“全世界可以免费交谈”。事实稍有不同,但很有趣 。
许多年前的某地,Niklas和其他伙伴开始了关于要让全世界免费交谈的想法。 因此他们需要给它一个名字。他们提出的一个名字是:“Sky peer-to-peer”,其缩写就是“Skyper ”。 但是因为在Internet世界,一些域名已经与“skyper”关联,因此他们想出一个变体,仅仅去掉字母r,变成“Skype”。 它很好听,而且那些域名也有效。
第一部分 介绍
Skype 是一个基于P2P的VoIP的客户端程序,他允许与其他Skype客户端软件之间进行通话并发送文字消息,非常像MSN和雅虎IM。具有语音通话,即时消息,语音会议,好友列表,但所使用的协议却是完全不同的。
就像他的前辈Kazaa一样,他是基于Peer to Peer对等网的。在这个对等网络中有两种结点,普通主机和超级结点(SN)。普通主机结点是一个可以语音通话和发送文本消息的应用程序;一个超级结点。在Skype网络中,一个超级结点是一个普通结点的终点。任何一个有公网IP,足够的CPU,内存资源和带宽的普通结点都将成为一个候选的超级结点。每个普通结点必须连接到一个超级结点并且在登录服务器验证。除了Skype结点本身外,登录服务器也是Skype网络中非常重要的组成部分,因为他存放着每个Skype用户的用户名和密码。这个服务器来保证用户名的唯一性。从Skype1.2版开始,以后版本的Skype把好友列表存储在登录服务器上。
除了登录服务器外,还有SkypeOut和SkypeIn服务器用来提供PC-to-PSTN和PSTN-to-PC呼叫的桥接。SkypeOut和SkypeIn服务器在PC-to-PC模式的呼叫中并没有扮演任何角色。所以,我们认为登录服务器是Skype的P2P网络中唯一的中心组织。上线和离线用户信息以分散的方式传播。
我们认为,每个Skype节点使用STUN协议的变种来确定它们位于何种NAT防火墙的后面。我们并且相信, 没有全球性的NAT和防火墙穿透服务器,因为如果有的话,在我们多次实验中Skype结点将会在登录和通话时交换传送信息。
每个Skype网络就是他所能达到的范围,因而每个Skype客户端(SC)需要创建和维护一个它所能达到结点的表,在Skype中,这个表被称为主机缓存(HC),包含了超级结点的IP地址和端口号,从Skype1.0版本开始,HC被存储在一个XML文件中。
Skype主张使用第三代P2P网络技术或者全球搜索目录技术来保证如果一个Skype用户在过去的72小时内登陆过Skype网络,可以快速查找这个用户。
Skype使用的语音编码允许它使用大约32kb/s的带宽来维持一个合理的语音质量。Skype使用TCP来维护信号,使用TCP和UDP来传送媒体数据。
本文剩余的部分将作如下组织。第二部分描述了Skype软件和Skype网络的关键组成部分。第三部分描述通过反向工程试验得到的Skype协议。第四部分论述了Skype的关键过程,比如登录,用户搜索,呼叫信令,媒体传送和编码,定时器,详细的流程图。第五部分论述了电话会议。第六部分论述了通过实验得到的Skype与MSN,Google Talk,Yahoo 等软件的比较。给出了一个在登录过程中超级结点和Skype客户端程序建立TCP连接结点的世界地图。
第二部分 Skype软件的关键构成
每一个Skype客户端在一个特殊的端口侦听呼入信号,维护超级节点列表,使用的音频编码器,维护好友列表,对信息进行端到端的加密,确定位于何种NAT或防火墙之后,这部分描述了他们的组成和详细的功能。
A..端口
每个Skype客户端(SC)都会打开一个端口号来侦听TCP或UDP链接,这个端口号可以在链接对话框中配置。SC在安装的时候随机选定一个端口号。此外还会侦听TCP的80和443端口来等待http或者https的链接。Skype没有默认的TCP或UDP服务端口,下图显示了一个Skype链接设置快照,里面显示了Skype侦听呼入的端口号。
B.主机列表
主机列表提供了超级节点的IP地址和端口号,由Skype客户端程序按照一定的规则创建和维护。他是Skype流程中最有争议的部分,在0.97版中,最后一次有效的条目必须存储在主机列表中,所谓有效的条目就是一个IP地址和端口号,在登录的时候,Skype试图建立一个TCP链接来与主机列表中任何条目交换信息,如果无法做到则报告登录失败。在1.2以前版本中如果不能与HC中任何条目建立TCP链接,Skype将试图与Skype内置的7对IP地址和端口号对建立TCP链接。Skype客户端在Window xp中把这个主机列表存储在一个shared.xml文件中,这个文件位于C:/Documents and Settings/<XP User>/Application Data/Skype.在Linux中存储在$(HOMEDIR)/.Skype.在运行两天以后大约有200个条目被存储在这个文件中。这个列表中的条目不一定是最新的,对于其他对等协议来说有一个指针列表,来快速查找一个结点。
C.编解码器
在我们的试验中,我们观察到Skype使用了iLBC , iSAC , iPCM 编解码器。这些编解码器是GlobalIPSound开发的。从1.4版开始Skype编解码器所允许频率在50- 8,000 赫兹,在这一范围内的声波会被编码。
D.好友列表
在XP中,Skype存储好友列表信息在一个XML文件‘config.xml中。这个文件位于C:/Documents and Settings/<XP user>/Application Data/Skype/<skype user id>。在Linux中位于$(HOMEDIR)/.Skype/<skype user id>.从XP中的1.2版开始好友列表同时被存储在IP地址为212.72.49.142的登录服务器中,好友列表未经加密的存储在本机计算机中,下图显示了config.xml的片段
<CentralStorage>
<LastBackoff>0</LastBackoff>
<LastFailure>0</LastFailure>
<LastSync>1135714076</LastSync>
<NeedSync>0</NeedSync>
<SyncSet>
<u>
<skypebuddy1>2f1b8360:2</skypebuddy1>
<skypebuddy2>d0450f12:2</skypebuddy2
显示了两个好友,每个好友后面有四字节的数字,如果两个Skype客户端有同一个好友,这个数字并不相同
E.加密技术
Skype官方网站声称,Skype使用了AES加密算法,这一算法被美国政府部门使用。Skype使用256bit密钥就会产生1.1*1077种可能。Skype加密了所有语音呼叫和即时消息的内容。Skype使用1024bit的RSA算法对称协商AES密钥,公钥在登录服务器时被服务器使用1536或者2048位的RSA算法来验证。
F.NAT与防火墙
我们认为,每个Skype节点使用STUN和TURN协议的变种来确定它们位于何种NAT防火墙的后面,Skype客户端定期刷新这些信息,这些信息也被存储在shared.xml文件中。
一个Skype客户端不能阻止自己成为一个超级结点。
第三部分 实验
我们实验了Windows1.4版和linux1.2版,使用了通信分析,共享库,系统调用中断等技术分析了Skype协议的各个方面,memgrp工具用来分析Skype运行时使用的各种寄存器。MaxMind用来查看IP地址对应的国家和城市。下面我们详细的解释在不同平台下对Skype客户端所做的实验
A.Skype1.4版本
这一版本是基于Windows的,我们通过分析了解到了他的主要运行机制。在两台XP的机器上安装了这一版本的客户端,每台机器使用3G 奔4 CPU,1G内存,10/100M网卡,连接到100M网络上。
我们在三种不同网络环境下进行了实验,第一种,两个Skype客户段均有公网IP,第二种,有一个客户端位于仅开放有限端口的NAT之后,第三种,两个客户端都位于仅开放有限端口的NAT之后并且UDP受限。NAT和防火墙的机器运行的是Mandriva Linux10.2,连接到100M以太网,NAT使用Linux的iptables配置。使用Etheral和NetPeeker来监控网络传输。NetPeeker用来调整带宽来分析Skype在网络阻塞情况下的操作。
B.Skype.1.2版本
这是一个Linux下的版本。使用了共享链接库,系统调用中断等技术来获得Skype协议更多的技术细节。在Linux下程序启动时,动态连接允许在其他任何动态库导入之前导入LD_PRELOAD环境变量,这就使得覆盖导入函数成为可能,比如strcpy()或者send()。Austin Godber 提供了一个非常好关于这项技术和函数截获技术的指南。
在我们的试验中,我们通过使用X-Win32使用两台linux机器显示输出,所以我们能在一台机器上使用Skype不同的实例。然而此时声卡设备不能使用。为了客服这一问题。我们通过以上技术重载了open(), close(), select(), and ioctl()等函数调用。相当于创建了一个虚拟声卡。
所有的实验都在2005年的十一月和十二月完成。
在剩余的部分中任何涉及到覆盖调用的部分都是在Linux下的1.2版Skype中实验的。Window中是在1.4版下实验的。
第四部分 Skype程序流程
Skype的功能可以分为以下部分:启动,登录,用户搜索,呼叫链接的建立和断开,媒体传送,即时消息,这一部分我们将详细描述每一步。
A.StartUP
当SC1.4 第一次安装并运行时,将会向Skype服务器(Skype.com)发送一个HTTP1.1的请求,这个请求的首行将包含关键词installed。
0.97版的这一详细信息如下:
GET /ui/0/97/en/installed HTTP/1.1
User-Agent: Skype™ Beta 0.97
Host: ui.skype.com
Cache-Control: no-cache
The 200 OK response SC received for this GET request:
HTTP/1.1 200 OK
Date: Tue, 20 Apr 2004 04:51:39 GMT
Server: Apache/2.0.47 (Debian GNU/Linux) PHP/4.3.5
mod_ssl/2.0.47 OpenSSL/0.9.7b
X-Powered-By: PHP/4.3.5
Cache-control: no-cache, must revalidate
Pragma: no-cache
Expires: 0
Content-Length: 0
Content-Type: text/html; charset=utf-8
Content-Language: en
GET /ui/0/97/en/getlatestversion?ver=0.97.0.6 HTTP/1.1
User-Agent: Skype™ Beta 0.97
Host: ui.skype.com
Cache-Control: no-cache
HTTP/1.1 200 OK
Date: Tue, 20 Apr 2004 04:51:40 GMT
Server: Apache/2.0.47 (Debian GNU/Linux)
PHP/4.3.5 mod_ssl/2.0.47 OpenSSL/0.9.7b
X-Powered-By: PHP/4.3.5
Cache-control: no-cache, must revalidate
Pragma: no-cache
Expires: 0
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Content-Language: en
2
96
0
B.登录
登录也许是Skype操作中判断函数最多的部分。在Skype客户端登录服务器时,服务器要判断用户名和密码,广播登录消息给好友,判断位于何种NAT和防火墙之后,查找有公网IP的Skype结点,检查是否有新版本的Skype客户端。
1登录过程
对于库函数重载的描述在上一部分我们已经描述过了,我们重载了connect(),sendto()这样的函数,然而调用时总是返回失败,我们允许一个TCP链接到本机后,因为如果不能建立这个链接Skype将拒绝运行。每当connect() 和 sendto()函数被调用时我们打印了系统时间,这样就准确的描述了Skype发送登录信息的时间。此外我们在运行Skype之前删除了HC XML 文件。然后我们运行Skype并试图登录,我们观察到SC发送了一个18字节长的UDP包到每个默认的HC的IP和33033端口,如果5秒后没有返回,则试图链接每一默认HC的TCP33033端口,如果依然失败,则在6秒后重复整个过程。我们运行了15分钟,奇怪的是Skype一直没有报告登录失败。以下是该过程的流程图:
开始
发送 UDP 包到7个内置
的SNs 端口号 33033
6秒内没有响应
否
是
尝试TCP 链接到7个内置
的 SN IP端口号33033
成功
链接
是
否
等待6秒钟
图3 Skype登录过程 SC发送18字节长的UDP包给每个内置的SN,5秒后尝试TCP链接所有内置SN的33033端口,此时登录服务器并没有出现。
2005年7月我们对linux1.0版做了相同的实验。结果发现Skype试图链接每个SN IP的80和443端口。很多防火墙软件允许TCP的80和443端口链接,然而在linux1.2版本分钟没有观察到这一行为。在HC文件被删除后我们观察到了相同的情形,所以我们认为这7对HC地址和端口号是硬编码在Skype 可执行文件中的。我们观察到。在一个Skype网络中一个SC必须建立一个TCP链接到SN。否则它将报告注册失败。
在另一个试验中,我们在SC NC中填写了一个无效的IP和端口号对,起初,SC不能建立一个TCP链接到这个无效的IP和端口号对,然而过了一段时间后他却建立了一个TCP链接到内置的SN。然而此时没有任何IP地址和端口号出现在HC中。这就让我们更加确信某些SN是硬编码在Skype 可执行文件中的。
为了观察在一次成功登录中,SC与其他实体交换的最小信息。我们做了如下实验。
我们删除了HC,并且允许了TCP和UDP的向内和向外的连接,此时一个HC被创建了,开始尝试登录,并且登录成功。我们使用同一用户ID多次重复以上试验。下图显示了SC,内置SN,SN和登录服务器之间交换的最小信息。
SC 195.215.8.145:33033 (内置的超级结点)
UDP 41B
UDP 64B
SC SN: (保密的原因IP地址没有显示)
TCP 357B
TCP 4032B
SC
UDP 18B
UDP 18B
SC 195.215.8.141:33033 (登录服务器)
TCP:SYN
TCP:ACK
TCP 5B (1)
TCP 5B (2)
TCP 413B (3)
TCP 222B (4)
图4 SC,内置SN,SN和登录服务器之间交换的最小信息,B代表字节,数据长度为有效长度
在实验中我们观察到,第一次和第二次发送到登录服务器的消息是一样的,甚至在使用不同用户ID时也是这样。第一个消息的十进制表示为22 3 1 0 0第二个十进制表示为23 3 1 0 0。在我们的实验中,大部分情况下只有四种信息在SN和登录服务器之间进行交换,信息的长度总是相同的。消息3和消息4在每次登录过程中是不同的。然而这两个消息有一个相同的四字节长的消息头,这个消息头的十进制表示和消息1,2是相同的。消息3的第5个字节的十进制值为205。观察后,我们在偏移地址为[消息头长(5)+205]的地方发现了23 3 1 0这个消息头,在这个消息头后边的那一位的十进制的值为198。(5+205+5+198=413)*消息4的第5个字节的值为217,正好是消息体的长度(5+217=222)。
译者注*在Winidows版3.0中消息3的长度变成了466,原来值为198的地方的值变成了251,其他未变。
注意在SSL 消息中, 第一字节表明消息类型,下二个字节表明SSL 版本。值22(0x16)对应这SSL的消息类型为client_key_exchange,值3 0对应于SSL 版本3.0 。从SC发往登录服务器的消息包含消息头22 3 1 0,它表明, Skype 在登录消息中使用了SSL的部分消息头。同以上的实验部分我们使用了相同的设置,并在登录时使用了一个无效的密码,结果消息1,2,3的长度是相同的。消息4返回了一个18字节的标志表示登录失败,4字节消息头后的第5字节的十进制值为13(5+13=18)。
我们判断阻止Skype登录是可能的,随后我们做了以下实验。结果登录却成功了。我们关闭了SC,重写了connect()函数,并尝试链接登录服务器IP,结果返回了错误信息。SC运行和登录却是成功的。我们注意到,含有十进制表示的22 3 1 0 0初始登录消息结点的IP地址被发送了,在我们重写的connect()函数中,我们禁用了这一IP地址,之后我们启动Skype并试图登录,奇怪的是居然登录成功。在Skype尝试登录前我们在connect函数禁用了IP地址,我们总共禁用了6个IP地址。然而Skype依然登录成功。依据这一实验我们判定Skype通过SNs发送了登录消息。这是一个明显的变化,0.97版能简单的阻止登录服务器IP来阻止登录。
接下来,我们重写了send函数,然后调用,结果当他看到前四个字节为22 3 1 0后总是返回错误。注意这是在图4中消息1和3的消息头。此时Skype开始尝试登录,使用不同用户ID多次登录后依然不成功。因而,通过发送前四个字节为22 3 1 0的包来阻止Skype用户登录是可行的。但是,如何保证任何防火墙规则不会组织他的通信是我们所关心的。
我们使用Windows下的1.4版的Skype来了解他在上面所说的三种网络环境中的登录行为。为了这一实验,我们卸载了先前版本的Skype,清理的注册表中相关的设置。安装了一个新版的Skype。表1总结了这些实验的结果。详细的过程在V0.97版的报告中有记载。
表 I
SKYPE (VER 1.4) 登录实验概要
Skype机器所处环境 |
数据交换 |
登录时间 |
两个都是公网IP |
10K |
3-7m |
端口受限的NAT |
11K |
3-7m |
UDP受限的防火墙 |
7K |
35m |
在多数的登录尝试中我们观察到SC总发送一个ICMP包到以下地址。204.152.*(美国), 130.244.* (瑞典), 202.139.* (澳大利亚), 202.232.*(日本).发送这个消息的原因我们还不清楚。通过分析发现他们位于不同的大陆。
通过前两个实验,我们观察到Skype登录成功后向22个结点发送和接收了数据。
2登录服务器
一个SC连接到一个SN后,SC必须通过登录服务器验证自己的用户名和密码。登录服务器是Skype P2P网络中唯一个中心组件。他存储了Skype用户的用户名密码,并确保用户名唯一。SC的每次成功登录都必须在登录服务器验证自己的用户名和密码。在试验中我们观察到每个SC总是使用TCP链接到IP地址为212.72.49.141或者195.215.8.141中的一个来交换信息。所以我们判定这两个结点应该是登录服务器。使用探测工具没有探测出这两个IP的域名信息。但是探测出服务器212.72.49.141在荷兰,服务器195.215.8.141在丹麦,好友列表服务器为212.72.49.142,所以我们认为他也是登录服务器的一部分。
3内置结点
我们列出了在一次失败的登录中出现的7对默认的IP地址和端口号。其相应的IP地址和主机名请参看表II。可以看出每个SN是由Skype自身维护的。
表II |
|
|||
使用REVERSE LOOKUP 得到的IP地址和主机名的对应表 |
|
|||
IP address:port |
Reverse Lookup Result |
Authority Section |
|
|
66.235.180.9:33033 |
sss1.skype.net |
ns1.hopone.net |
|
|
66.235.181.9:33033 |
No PTR result |
ns1.hopone.net |
||
212.72.49.143:33033 |
No PTR result |
ns07.customer.e |
||
|
|
u.level3.net |
|
|
195.215.8.145:33033 |
No PTR result |
ns3.DK.net |
||
64.246.49.60:33033 |
rs-64-246-49- |
ns2.ev1.net |
||
|
60.ev1.net |
|
|
|
64.246.49.61:33033 |
rs-64-246-49- |
ns2.ev1.net |
||
|
61.ev1.net |
|
|
|
64.246.48.23:33033 |
ev1s-64-246-48- |
ns1.ev1.net |
||
|
23.ev1servers.net |
|
|
|
4判断NAT和防火墙
我们推测一个SC能够在登录时判断是否位于NAT或防火墙之后。我们猜测一个SC至少有两种方法判断这些信息。一种可能是它能通过使用STUN协议的一个变种与SN通信来判断这些信息。另一种可能是在登录过程中与SN建立的TCP链接后发送并从某些结点接收了信息。我们推测SC使用STUN协议的一个变种来判断位于何种NAT或防火墙之后。一旦判定,SC存储这一信息在shared.xml文件中,并周期性的更新这一信息。我们还不清楚自从Skype消息被加密后如何更新这一信息。
5获取最新版本
在SC登录过程中,发送一个HTTP 1.1请求给Skype服务器判断时候有可用的新版本。该请求的第一行包含关键词getlatestversion。在首次启动时连同HTTP请求一起发送的只有文本信息。
6登录过程用时
在本文的第三部分我们描述了在三种不同网络环境中登录Skype网络所使用的时间。这个实验中, HC 已经包含了二百个词条最大值。在有公网IP和NAT端口受限的情况下整个登录过程所用时间大概为3-7秒。如果位于UDP受限的防火墙后则需要35秒左右。我们猜测在UDP受限的防火墙后时他发送UDP包到HC中的20个条目SN。在断定位于DUP受限的防火墙后,他将试图建立一个TCP链接到HC中的条目,并最终能够链接到一个SN。同样,一个位于端口受限的NAT或UDP受限的防火墙之后的SC在随后的登录过程中将花费5-10秒,这就表示SC保存了最后的链接信息在一个文件中。
C.用户搜索
Skype使用他的全球索引技术来查找一个用户。Skype声称他的查询是分布式的,如果一个用户在过去的72小时内登录过就肯定能够找到这个用户。更广泛的测试说明Skype总能够找到一个用户,如果一个用户在过去72小时内登录过,不管是公网IP还是私有IP。
Skype使用的不是公开的协议,并且所有信息都经过加密。然而对于登录,我们能从适当的准确度来判断不同的有关实体,他不可能做如此的搜索,因为我们无法在一个SN上来追踪消息。而且我们无法精确的了解SC链接到SN的所有细节,然而我们依然观察并给出了三种不同网络环境下的消息流动。
每一个SC都有一个搜索对话框,当用户输入一个用户ID并按下搜索按钮后,SC开始精确的搜索一个用户,对于一个有公网IP的SC,发送一个TCP包到他的SN,这就表示SN给SC发送会8个结点的IP地址和端口号,交换信息完成后,SC发送UDP包到这八个结点,如果不能找到这个用户,通过TCP通知SN,SN由发送了16个不同结点的信息,SC发送UDP包到这十六个结点,这一过程将循环执行,直到找到这个用户或断定这一用户不存在。平均起来SC需要查询超过24个结点,这一过程大约需要3-4秒。
SC SN
TCP 13B
TCP 48B
UDP 171B N1
UDP 18B N1
UDP 54B N2
UDP 18B N2
……
图五 一个SC1.4有公网IP时成功搜索一个用户的消息流。B代表字节,N代表结点,消息长度为有效长度(不包括数据包的包头)
一个位于端口受限的NAT之后的SC在SN和一些在登录过成功有返回UDP信息的结点之间交换信息,消息流程如图六所示,这个搜索过程大约需要5-6秒。
SC SN
TCP 13B
TCP 48B
SC N1, N2, N3, N4
UDP 91B
UDP 18B
UDP 54B
UDP 25B
.……
图六,一个SC1.4在端口受限的NAT之后时成功搜索一个用户的消息流。B代表字节,N代表结点,消息长度为有效长度(不包括数据包的包头)
在第三种网络环境下,SC发送搜索请求给SN,SN来执行这个查询并把查询结果返回给SC。它不像一个有公网IP的SC那样查询,此时SC不与任何结点链接,这就表示SC知道位于UDP端口受限的防火墙之后。消息流程如图七所示,这个搜索过程大约需要10-15秒。
SC SN
TCP 6165B
TCP 1130B
图七,一个SC1.4在UDP端口受限的防火墙之后时成功搜索一个用户的消息流。B代表字节,数据交换仅仅在SC和SN之间,消息长度为有效长度(不包括数据包的包头),消息大小为所有包的统计值。
在一些成功的搜索中我们观察到SC与登录服务器有信息交换,看来Skype在索所万一不成功的时候使用登录服务器作为一个会退的操作。对于一个不存在的用户名,SC总是链接登录服务器。
我们不清楚如果一个SC找不到一个用户如何终止这个查询。
搜索结果缓存
为了观察搜索结果是否缓存在中间结点。我们在SC1.4上做了以下实验。位于端口受限的NAT和UDP端口受限的防火墙之后的用户A登录到Skype网络。拥有公网IP的用户B在另一台机器上登录到Skype网路。用户B搜索用户A,搜索过程花费了10-11秒。接下来我们在B用户所在的电脑上卸载SC,清理缓存和注册表,然后从新安装SC,B用户再次搜索用户A花费了3-4秒,这一实验我们在不同的日期多次实验,结果都很相似。
所以我们推断Skype网络的中间结点缓存了用户搜索的结果。
Skype用户允许使用通配符搜索其他用户,我们认为在两个SC实例中使用同样的通配符搜索用户ID返回结果相同,为了证明这一点我们做了以下实验。我们在两天机器上开启两个Skype客户端实例,使用相同的通配符搜索用户ID,然而返回结果并不是完全相同。在所有的通配符实验中搜索结果总不是完全一样。
D.呼叫建立和拆线
在上述三种网络环境中SC1.4的呼叫建立,对于每种环境,我们考虑到了对于那些在好友列表里的用户的呼叫和对于不再好友列表里的用户的呼叫。需要注意的是,其中最重要的是都是使用TCP链接来发送控制信号的。
对于不在好友列表里的用户,呼叫信号的建立等于用户搜索加上呼叫信号。因此我们主要讨论被呼叫者在好友列表里的情况下的呼叫建立。
如果两个用户所使用的机器都有公网IP,并且相互之间都在对方的好友列表里。当按下呼叫按钮后,呼叫者将建立一个TCP链接到被呼叫者,通过TCP链接发送信号信息。呼叫者与被呼叫者之间的流程如图八。
呼叫这按下拨号盘
呼叫者 被呼叫者
TCP 1159B (4)
TCP 1536B (4)
图八 SC1.4下呼叫者与被呼叫这之间的信息流,两者都有公网IP,双方都在对方的好友列表中,B表示字节,消息结果被合计,消息的大小为近似值,括号中的数字表示在那个方向上发送的数据包的数量。
在调用者和被调用者之间最初的信息交换显示发起-响应机制的存在。呼叫者通过UDP与结点之间进行了通信(图八中没有显示),这一过程大约交换了6K字节的信息。
在第二种网络环境中,呼叫者位于端口受限的NAT之后而被呼叫者拥有公网IP,最初信号信息并不直接在两者之间流动,呼叫者首先与一个在线结点通过TCP链接交换信息,然后由这个结点转发这个呼叫信息,这个呼叫建立以后,媒体信息立即在两者之间使用UDP流动。图九显示了这一信息流动过程。这一过程大约交换了8千字节的信息。
呼叫者 被呼叫者
UDP 271B (5)
UDP 221B (7)
呼叫者 被呼叫者
TCP 1554B (8)
TCP 1176B (9)
呼叫者 SN
TCP 184B (6)
TCP 1269B (6)
呼叫者 其它
UDP 748B (20)
UDP 3287B (20)
呼叫者 其它
TCP 265B (12)
TCP 77B (6)
呼叫者 被呼叫者
Meda: UDP
语音包的大小在70-100字节之间
图九 在端口受限的NAT之后的SC呼叫有公网IP的SC的信息流图,B代表字节,并非所有包都显示出来了,信息包被合计,消息的大小为近似值,括号中的数字表示在那个方向上发送的数据包的数量。
在第三种网络环境中,呼叫者和被呼叫者都是通过TCP与在线的结点进行通信,呼叫者通过TCP链接把语音信息传送给在线结点,然后由该结点转发给被呼叫者,反之亦然。图十显示这这一过程,这中间大学交换了8千字节的数据。
呼叫者 SN
TCP 713B (7)
TCP 3464B (8)
呼叫者 转发者
TCP 124B (4)
TCP 45B (4)
被呼叫者
TCP 51B (3)
TCP 117B (4)
呼叫者 转发者 被呼叫者
Media:TCP Media:TCP
呼叫者 N1 N2 N3
TCP 19B
TCP 19B 被呼叫者
TCP 19B
TCP 19B
呼叫建立以后,呼叫者与被呼叫者之间通过N1 N2 N3建立的TCP链接的速率大约为3 msg/s
图十 呼叫双方都在防火墙后的情况下建立呼叫后数据流情况,B表示字节,N表示结点。并非所有包都显示出来了,信息包被合计,消息的大小为近似值,括号中的数字表示在那个方向上发送的数据包的数量。
在呼叫者与被呼叫者之间建立一个路由节点确实有优势,首先他提供了一种机制来解决呼叫双方在NAT和防火墙之后的问题。其次,如果一个在NAT或防火墙之后的用户发起一个语音会议,其他有公网IP的用户要参加这个会议,这个结点就可以提供混音服务并把语音广播给参与会议的用户。但是不足之处在与将会有非常多的消息流通过这一结点。一般用户不希望有这么多的数据流通过自己的机器。
当呼叫结束需要拆线时,两个有公网IP的用户使用TCP传送拆线信息,其他情况则在呼叫者和被呼叫者与他们的SN之间进行TCP传输拆线信息。图十一展示了两个有公网IP的用户在拆线时的情形。
呼叫者 被呼叫者
TCP 68B (4)
TCP 70B (4)
图十一 呼叫双方又有共有IP时的拆线过程,信息包被合计,括号中的数字表示在那个方向上发送的数据包的数量。
对于第二和第三种情况,依然是使用TCP来传送拆线信息,我们并没有给出这些消息的流程,因为这中间没有任何我们感兴趣的信息。
对于SC v1.4, 我们进行了实验来确定如果呼叫双方都有公网IP并且互相在对方的好友列表中,呼叫信号是端到端链接。我们在两台有公网IP的Windows机器上安装了两个SC实例,保证双方均在对方的好友列表中。成功登录后,等到双方均能发现对象已经在线,也就是在双方的好友列表中对方的图标变成绿色。此时已经没有TCP链接在两个SC之间。使用NetPeeker阻断了除了对方IP以外的所有进出链接通道,结果呼叫依然成功了。
我们又阻断了双方的TCP链接通道,结果呼叫失败了。
通过以上实验可以断定,呼叫双方使用端到端的通讯,呼叫信号使用TCP链接
E.媒体传送和编码
如果两个SC(v1.4)都有公网IP,那么呼叫双方立即使用UDP通讯传送语音信息,使用的端口号是在配置端口号对话框中设置的那个端口,语音包的大小各异,在40-120字节之间。对于两个使用100M以太网链接到互联网的用户来说,几乎没有网络阻塞,每一秒中大约传送85个语音包,语音传输所使用的上传和下载的总带宽约为5千字节每秒,这和Skype官方所称的3-16千字节每秒是吻合的。
如果呼叫双方任何一个或者两者均在端口受限的NAT之后,他们互相发送语音包。语音包的大小各异,约在40-110字节之间,这里指的是UDP包的有效负荷。带宽占用约为5千字节每秒。
如果双方均在端口受限的NAT之后并且UDP端口受限,则双方使用TCP传送语音包,并且这些语音包需要另一个在线的结点进行中转。TCP语音包的有效负荷约为30-90字节,上下行贷款占用总计约为5.5千字节每秒,SC需要使用中转的TCP链接来传送语音信息。
在所有的三种情况中,均使用iSAC编码器。
Skype协议似乎更喜欢使用UDP协议来传送语音信息,一个在NAT或防火墙之后的SC,如果防火墙允许使用UDP通讯,那么他将使用UDP传送语音信息。
1(沉默压缩)Silence Suppression
Skype不支持沉默压缩技术。我们观察到在通话双方均未发声时,语音包依然在双方之间传送。虽然增加了带宽占用,传送这些没有语音的语音包有两点好处,其一,将与NAT维持UDP绑定,其二,这些语音包可以用来播放背景声音。同样双方在使用TCP链接传送语音时,没有语音的语音包依然会被传送,其目的是避免改变TCP窗口的大小使得一些RTT再次达到最大值而造成TCP阻塞(译者注,在TCP转发过程中会发生,具体信息参阅TCP转发的相关信息)。
2保持通话状态
Skype允许双方对等的保持通话。一个在NAT之后的SC在运转以前必须保证NAT绑定UDP是有效的。平均起来,一个SC每三秒中将发送一个UDP包给与他对等的SC,SN或者一个在线的充当媒体信息代理的Skype结点,来维持会话。在保持一个会话时,除了UDP包外SC还有周期性的发送TCP包到这些端点。
3编码频率的范围
我们做了很多实验来检验Skype允许编码的音频的频率范围,在两个SC之间建立一个通话以后,我们使用NCH频谱发声器产生大量的不同频率范围的声波信号,并把这些信号在通话双方使用,通过测量接收到的声波的频率范围来确定这一范围。结果我们观察到Skype允许编码音频的频率范围为50Hz-8000Hz。
我们使用NetPeeker把给Skype的上下行带宽各自限定在1.5k字节每秒,结果发现Skype编码的范围没有改变,还是50Hz-8000Hz。
4阻塞
我们使用Net Peeker调整上传和下载的带宽,然后检查Skype在低带宽环境下语音质量,结果发现上下行带宽分别为2千字节每秒是必须的,在上下行带宽分别为1.5千字节每秒时的语音几乎是无法听清的。
F.信息保持
我们在三种不同网络环境下,观察了SC v1.4通过TCP发送一个刷新消息到他的SN的情况。一个有公网IP的SC每隔120秒发送一个更新信息。
SC SN
TCP 2B
TCP 2B
图12 一个有公网IP的SC发送刷新信息到SN
第五部分 电话会议
我们使用SC v1.4在三种环境下观察了三用户参加的网络会议功能。为了描述方便,我们来对用户或者机器进行命名。三个用户分别命名为A,B,C。A用户使用笔记本,1.6G Pentium 4 CPU,512M内存。B和C机器使用3G Pentium 4 CPU 1G内存。首先在第一种环境中,三台机器都有公网IP。A用户发起呼叫并于B建立链接,B又邀请C加入会议。然后使用Ehtereal 抓包。分析发现B和C通过UDP传送语音包到A,A扮演一个混音器的角色,它混合自己和B的包给C,同时混合自己和C的包给B。图十三显示了这一过程。
A+C A A+B
B C
C
B
图十三 Skype三用户会议
在第二种网络环境中,B和C在端口受限的NAT之后,A有公网IP,最初,用户A和B建立呼叫链接,相互之间使用UDP发送语音包。用户A保持与B的通话,然后与C建立会话,这时A与B和C开始了一个三用户会议。这是观察到B和C都通过UDP发送语音包给A,A混音自己的语音包后进行相应的转发。
在第三种网络环境中B和C位于端口受限的NAT和UDP受限的防火墙之后,A有公网IP。用户A向B和C发起一个网络会议,结果观察到B和C通过TCP发送他们的语音包到A。A混音自己的语音包后进行相应的转发。
如果用户B和用户C正在通过转发器D进行通话,此时B在向A发起一个语音会议,转发器D依然会存在于B和C之间。
我们在v0.97上做了相同的实验,发现大多数情况下总是性能强大的机器被选作会议的主持者。
对于三方会议来说,Skype并不做充分的过滤。
第六部分 其他实验
不同于MSN 和雅虎IM那样如果一个用户同时在其他机器上登录则当前用户必须退出,Skype允许用户同时在多台机器上登录。呼叫信息能够被所同一个用户ID的多个登录所接收,当其中一个登录接听电话后,其他呼叫立即被中断。同样,即时消息将被传送到同一个用户的多个登录中。
一个Skype客户端被选为SN基于以下几个因素,CPU可利用率,带宽。任意选择一个SC作为SN填充HC是不可能的。做出这个结论依据以下实验。建立两个Skype在线结点A和B。A连接到Skype网络中,在它的HC中只有一个条目,我们把A的超级结点叫做SN_A。然后修改B的HC,让它仅仅包含A的IP地址和端口号,当B登录Skype网络时,它链接到了另一个超级结点。
为何观察是否有不同的密钥嵌入到了Skype的执行文件中,我们在一周的不同时间下载了Skype的安装文件,结果发现这些文件并没有什么不同。
如果两个Skype用户位于同一个NAT之后,在他们建立一个通话后,语音流就会立即通过内网在两者之间传送。如果两个用户位于两个不同的NAT之后,在线路上将会发现一些ARP包。这就表示Skype在试图判断是否在两者之间能够之间通讯。
A. Skype与MSN,Google Talk,Yahoo语音服务对比
我们按照一定的规则测量了Skype,Yahoo,MSN和Google Talk之间的语音服务质量。
在我们的实验中主要是测试声音从嘴到耳之间的延时的不同,在一端发出语音,在另一端就可以听到原始的声音和从听筒里传出来的声音,然后把这一混合声音在网络上传播,这样在一个媒体流中就可以听到这两个声音。我们就可以使用工具来分析这两个声音之间的时间差来计算网络语音的延时。
在实验中我们的输入信号是预先录制好的一段24秒的音乐文件。Skype,MSN,Yahoo和Google Talk软件分别安装在有相同硬件配置的使用Windows XP SP2的笔记本电脑上,每个笔记本都是用Pentium M 1.7GHz的CPU,1GB内存,都有公网IP,使用100M以太网链接到互联网。在两者之间建立语音会话,使用Etheral来分析他们发送语音包的过程。使用Cool Edit Pro2.1来记录8000Hz16bit的语音,每个实验记录四次,结果显示在表三中。延时的值是四次的平均值。
表三SKYPE, YAHOO, MSN和 GOOGLE TALK的比较
|
程序 版本 |
语音通讯前内存使用(主叫/被叫) |
语音通讯中内存使用(主叫/被叫) |
通讯前CPU优先级 |
通讯中CPU优先级 |
嘴到耳的延时 |
与标准延时差 |
Skype |
1.4.0.84 |
19 MB, 19 MB |
21 MB, 27 MB |
正常 |
高 |
96 ms |
4 |
Yahoo |
7.0.0.437 |
38 MB, 34 MB |
43 MB, 42 MB |
正常 |
正常 |
152 ms |
12 |
MSN |
7.5 |
25 MB, 22 MB |
34 MB, 31 MB |
正常 |
正常 |
184 ms |
16 |
G-Talk |
1.0.0.80 |
9 MB, 9 MB |
13 MB, 13 MB |
正常 |
正常 |
109 ms |
10 |
我们在试验中测试了另外三种客户端。Skype与其他三种不同的是在语音通话时CPU优先级提升到了高级。
B.Skype超级节点图
我们做了相关实验来观察Skype选择超级节点的机制,我们知道在登录的时候,一个SC必须总是链接到一个SN。我们利用这一事实,一个位于NAT之后的SC永远不可能成为SN,并且多数情况下总是连接到仅仅一个超级结点,同样的在紧接下来的一个登录,并不是再次连接到同一个超级节点,经过Skype在接下来很长一段时间里的多次登录,我们得到了一个关于Skype超级结点的快照。
对于这一实验我们使用AutoIt来让Skype自动登录和注销,AutoIt是一个Windows任务的自动化脚本工具。使用它我们让Skype程序每次登录时间保持30秒,登录间隔为10秒。我们运行了96个小时(四天)。使用netstat观察测试机TCP链接的IP地址和端口号,此时保证除了Skype没有其他的任何TCP连接,并且每次登录必须与一个SN建立一个TCP链接,使用netstat保存建立TCP链接的IP地址和端口号。理论上这一时期通过四天每次花费40秒钟应该有8640次登录。然而我们仅仅记录了8175次登录,这主要是因为在Windows上执行脚本时要花费一定的时间。除去重复的IP我们在这8163次登录中发现了898个超级结点。
使用MaxMind工具,我们测定了他们的经纬度,国家,城市,结果记录在下图中。MaxMind不能测定其中10次链接的IP的国家。所以我们的数据中记录了8153次成功的登录,894个超级结点。
对数据的处理结果显示如下:
SN的IP:美洲83.7%,亚洲8.9%,欧洲7.1%
在8153次登录中,2855(35%)的主机名有.edu后缀,分属于102所大学。
在894个结点中,前二十个结点收到43.8%的链接,前一百个结点收到70.5%的链接。
表四显示了每24小时SN的数量,其中包含了公共部分。需要注意总共有894个SN。
|
每天SN的数量 |
积累SN的数量 |
与前一天共有SN数量 |
第一天 |
224 |
224 |
|
第二天 |
371 |
533 |
42 |
第三天 |
202 |
699 |
98 |
第四天 |
246 |
898 |
103 |
表五显示了除了美国外收到链接数量的前五个国家。
国家 |
SN数量 |
台湾 |
256 |
以斯列 |
195 |
日本 |
168 |
法国 |
75 |
瑞士 |
55 |
表六显示了收到链接数量最多的五个大学。
大学 |
SN数量 |
哈佛大学 |
367 |
哥伦比亚大学 |
366 |
内布拉斯加-林肯大学 |
350 |
宾夕法尼亚大学 |
254 |
布鲁内尔大学 |
179 |
第七部分 结论
在这份报告中我们通过Skype的网络传输,截获共享库和系统调用,分析Skype协议的各种特性。可以说Skype可以几乎无缝的穿越任何NAT和防火墙。我们认为Skype客户端使用了STUN协议的变种来判断自己位于何种NAT和防火墙之后,Skype的这种穿透NAT和防火墙技术在很多应用程序中都有应用,例如网路游戏。它随机的选择发送和接收端口,使用TCP来控制语音传送,Skype是一个对等的网络,可以穿透任何NAT和防火墙,但是没有任何穿透NAT和防火墙的服务器,Skype使用TCP发送信号,他使用宽频率的GlobalIPSound语音编码,所有通讯都是经过加密的。
Skype的用户搜索技术还不是很清楚。我们猜测它使用了联合散列发,并且定期更新Skype用户的在线信息。Skype搜索机制在所有搜索用户失败时或者某些搜索成功时要传信息到登录服务器。
比较了Skype和MSN,雅虎通,Google Talk,Skype是其中语音质量和功能最强。
Skype是一个自私的应用程序。他总是试图找到最好的通讯网络,CPU资源来执行自己。在windows中使用语音通信时它改变自己的CPU执行级别为高级,通过路由自己的消息到SN来躲避阻断。这就意味着受阻的SC依赖于SN路由自己的登录消息来登录Skype网络。Skype用户不能阻止自己的机器成为SN,尽管这样,还是可以通过限定Skype应用程序的带宽来实现这一功能。理论上而言,如果所有用户都限定Skype应用程序的带宽,Skype网络中的SN会因为没有足够的带宽来中转呼叫而使得Skype网络崩溃。
在我们分析Skype协议的试验中,获取的那些截取和阻断的包可以用来对协议进行反向工程。像Ethereal这样的经典的抓包工具对于这些加密的数据包用处并不太大。共享库和系统中断截获技术可以把网络传输作为黑盒子来使用。