STUN client初试 (续)


在完成了最基本STUN客户端功能(发送Binding request,接收Binding response)之后,做了一些测试.
之前一直纠结在 端口号为何 返回的 与其它软件的返回结果 有出入. 当中.
于是疑心四起,在怀疑了NAT修改,字节顺序 之后,不停地调试....
然后发现我用0x1111去& 某个值, 而事实是 ,我应该用 0xffff . ( 囧0z)
但之后所做的种种测试,让我 决定再写一篇 用来备忘 STUN协议应该注意的很多重要细节。
同时也希望能帮助更多 还没接触过该协议的人,我相信我的这些记录能帮助他们少走弯路.
首先说说我为什么怀疑NAT修改, 这就引出了一个替代RFC3489 的STUN协议 : rfc5389.

rfc5389 在第一页就以Session Traversal Utilities for NAT的缩写 重名名了 老的RFC3489 STUN 缩写,
老实说我严重怀疑这篇的起草人在凑名字 -- 他们希望 rfc5389代替RFC3489 所有东西.包括 STUN 缩写.
呵呵,当然是开玩笑.其实rfc5389 之所以从新定义STUN 缩写,主要是STUN 不再是p2p的完全解决方案。
正如描述:
  STUN is not a NAT traversal solution by itself.  Rather, it is a tool
   to be used in the context of a NAT traversal solution.  This is an
   important change from the previous version of this specification (RFC
   3489), which presented STUN as a complete solution. 
而rfc5389 中描述的所谓的magic cookie (rfc3489bis-03中被加入)还有 XOR-MAPPED-ADDRESS Attribute(rfc3489bis-01中被加入)
即为了防止 某些手段较狠的NAT 对MAPPED-ADDRESS 的修改 .它的主要机制:
X-Port is computed by taking the mapped port in host byte order,
   XOR’ing it with the most significant 16 bits of the magic cookie, and
   then the converting the result to network byte order.  If the IP
   address family is IPv4, X-Address is computed by taking the mapped IP
   address in host byte order, XOR’ing it with the magic cookie, and
   converting the result to network byte order. 
(通过把MAPPED-ADDRESS 用异或运算 的 映射方式 映射为XOR-MAPPED-ADDRESS 从而逃过 网关修改)
(注意异或运算是其自身的逆运算,所以我们再异或一下就可以得出真实的MAPPED-ADDRESS了)


早在rfc3489bis-01中就用这样一句话作为引入XOR-MAPPED-ADDRESS 的解释:
Unfortunately, some NAT devices have been
   found to rewrite binary encoded IP addresses and ports that are present in protocol payloads.  This behavior interferes with the
   operation of STUN.  By providing the mapped address in an obfuscated
   form, STUN can continue to operate through these devices. 
幸亏我 调试半天 得到的原因不是 NAT对报文的修改.不过我们 应该知道 存在这样的情况。 那么在 MAPPED-ADDRESS不对时
有助于注意到这个极有可能被忽略的原因.(所以塞翁失马焉只祸福 , 感谢我的0x1111)


其次,我不得不提醒所有刚开始着手客户端协议的童鞋:网上铺天盖地的STUN 名字其实 背后隐藏着 是 它有很多版本的事实 .
以后提到STUN 我们需要说明它所指的版本.
要命的是,现在网上能找到的很多公开STUN服务器地址,他们apply的STUN版本还很多是rfc3489bis-02 版的,
也就是说,rfc5389 早在08年就出来,‘问世’ 有3 年了 ,很多STUN服务器 还使用 2005 年的rfc3489bis-02.(或许这就是对标准的反应速度)

更要命的是,
期间的每一版本(我并没有全看 且 看得不很仔细) 发生了很多重要变化
(从整个名字的更换 和 对其本质定义彻头彻尾的改变就可以见一斑) ,有些重要的定义 刚出现
就被下一版所否定(如我后面将举到的 rfc3489bis-02中对0x8020的定义),而客户端需要理解attribute. 这就造成了很多对该属性的无所适从.
甚至怀疑返回的结果,和STUN服务器的正确性. 所以明白一些重要的细节 及 他们在各个版本中的区别 对于STUN 客户端开发者来说,个人认为十分重要.
现在就举rfc3489bis-01中的例子,我对8个公开STUN服务器做了测试:
const char* g_STUN_ServerAddr[][2] = 
{
	{"stun.iol.unh.edu", "132.177.123.13"} ,
	{"stun.iptel.org"  , "213.192.59.75" } ,
	{"stun01.sipphone.com"  , "198.65.166.165" },
	{"stun.counterpath.com"  , "75.101.138.128" },
	{"stun.rixtelecom.se"  , "217.75.110.192" } ,
	{"stun.ideasip.com"  , "208.97.25.20" } 
	 
}; 
可以发现只有 stun.iptel.org 和 stun.ideasip.com 没有返回 0x8020的attribute ,可以看出他们仍用着rfc3489bis-02的协议。
怎么证明呢??
因为仅仅独有rfc3489bis-02 对其定义了. 而且定义还出现失误,因为rfc3489bis-03立即对其进行了纠正:
 Note:  Version -02 of this Internet Draft used 0x8020 for this
      attribute, which was in the Optional range of attributes.  This
      attribute has been moved back to 0x0020 as a Mandatory attribute. 
所以我们要了解 这些服务器所使用的协议,就算他们没有用最新的协议.也可以推断出他遵循的版本.
从而对其返回结果作出正确的反应.
此外stun.iptel.org 和 stun.ideasip.com 返回的结果 中带有0x5 和 0x4这两个attribute .
所以也可以推断出他们使用的 版本 在rfc3489bis-04 之前 .因为rfc3489bis-04中描述与上一版的区别:

o  Removed the usage of STUN for NAT type detection and binding
      lifetime discovery.  These techniques have proven overly brittle
      due to wider variations in the types of NAT devices than described
      in this document.  Removed the RESPONSE-ADDRESS, CHANGED-ADDRESS,
      CHANGE-REQUEST, SOURCE-ADDRESS, and REFLECTED-FROM attributes.

   0x0004: SOURCE-ADDRESS
   0x0005: CHANGED-ADDRESS 
好,下一步就准备 对 MAPPED-ADDRESS 进行一些打洞试验了 ,我真的渴望取得成功的那一天 .
也希望这些细节对 他人有用, 这样就真没白写了.
By ga6840

 

你可能感兴趣的:(STUN client初试 (续))