|
Ipv6测试实践散记 3 建立秩序
上一节里,我们看到了一些IPv6可能带来的问题,这一节,我们则找一些点,具体来说一下,可能会有些散乱。
我们已经提到过,很多时候并不是软件存在问题,而是设置的问题,比如你有一个程序在如下地址listening: hostA:19389,在IPv4环境下,你的程序或者从DNS,或者从其他途径把它翻译成IP 202.120.1.8:19389。接下来你的客户端发起一个连接请求,同样的也被翻译为这个地址,然后请求发出,连接成功。
在纯IPv6的环境下也比较简单,只不过地址变成了2002:0db8::00a1:19389。等一下,问题出现了,程序怎么知道19389是地址还是端口?这个问题就是IPv6设计之初没有考虑到的,所以随后他们做了补充,当v6地址出现在url的时候,必须加上square bracket,变成[2002:0db8::00a1]:19389。这里引出了第一个小麻烦,当你有一个GUI,同时接受IPv4,IPv6地址和hostname的时候,你的程序要做出判断,如果是IPv6地址的话,要加上 []。但是,如果用户输入的是hostname,而你这台机器又从DNS那里获得了IPv6地址,怎么办呢?没关系,我们把加[]的步序往后移,如果是hostname,先做主机解析,然后再判断是否v6。但是,是的,又是但是,如果我们需要保存这个地址,随后把它传给另一个软件呢,而那个软件可能拒绝,因为它认为[...]这个地址无效。这里,你不能指责那个软件,因为规范并没有规定地址上要加[],而只说当地址在url中有port时,为了避免混淆,必须加[],你传给对方的是地址,而不是url。所以比较好的方法是只有在组合url的时候才判断是否是IPv6地址,进而添加[]。这里还要注意一个问题就是,有些用户可能输入的时候自作聪明的加上了[](而且有的软件就是这样要求用户的),这里你又要多判断一个。。。重复一下,注意这里没有对错,只是不同的理解,但作为QA,有必要就此提醒开发,并就最终的决定建议technical writer添加相应的解释。
更大的麻烦出在IPv4/6混合环境。假设还是上面的情况,Server A和客户机 B是W2K3或者XP,使用一台W2K3做DNS服务器:对于Vista 和2008之前的Windows,你是无法使用纯IPv6的,即使安装了TCP/IPv6协议,也只能是两者共存。但是,我相信没有人有魄力宣称drop掉W2K3和XP,况且他们确实是支持IPv6的。好吧,那我们在DNS中只保留IPv6的global地址,这样当我们使用hostname的时候应该只会得到v6 global地址了,一切应该顺利吧?可是事实并非如此,连接以失败告终。那么我们先来检查下A的侦听,从A机做一个netstat -an,你会惊奇的发现它并没有在2002...那个global address上侦听,而是在fe80...的link local上。好吧,我们先不管这件事情,先不用hostname,直接在2002...的global address上侦听,连接,还是失败。那我们到B机器上来,看看怎么回事,做一下nslookup -type=AAAA Ahost(参数AAAA是指定要求v6,这是v6 address 在dns中的类型,不加的话默认是v4,你也可以用参数ANY,返回所有类型,大多数v6网路工具都有特别命令或者参数,可以自己查找该工具说明。) DNS会返回给你正确的地址2002...。再做一下ping hostA,你会惊奇的发现,它在使用v4地址。怎么回事?感觉有点乱吧,接下来会更乱,休息一下,然后我来解释为什么会发生这种情况:
首先,Windows除了DNS外,还支持netbios协议,这是一种很古老的协议(Windows真的很辛苦。。。一直要支持各种东西,这也是它的一个负担),他可以发现临近机器的地址,当然只可能是v4的,所以即使我们DNS里没有v4的信息,hostB还是可以知道hostA的v4地址,并且反映在那条ping的命令里。可是怎么解释A本身使用的那个fe80...的link local address呢?这里有两个原因,首先A机器同时拥有v4/v6协议,v6是更强的协议,因此首先找v6的,其次,因为是在本机,所以他很聪明的自动找到了这个link local地址(相比之下,solaris需要在ipnodes里面设置对应,很难说谁好谁不好,windows 这样是比较聪明,但有时候也是制造困惑。)且慢,既然是首先找v6,那为什么没有找到DNS里设置的那个global address呢?那是因为它跟本没有去DNS!如前所述这个link local是在本机找到的。因为我们忘记了一件事情,我们已经把机器移出了域,也没有了DHCP,也就没有了自动添加的domain suffix。其实这个事情在v4网络一样会发生,但是无关紧要的,因为netbios会给你一样的结果,但是由于我们现在的尴尬设置,才造成这个情况。你可以去Bhost验证,ping -6 hostA(强制V6协议),你会得到域名无法解析,这是意料之中的事情。所以我们要到网络设置里去手动添加后缀teslab.xxx.com。再试,连接成功,netstat -an,清楚的显示IPv6 global address和来自B的global a的dress 成功连接,世界清净了。
还没完,接下来我们来测试下次环境中的v4能力:在DNS中添加A的v4地址,然后让A显式的在v4地址上监听,连接,如你所猜想的,失败。原因和前面说的一样,v6是强类型地址,所以DNS也优先返回v6,B用v6的socket去连接v4的,当然是失败。而且即使你在B的host table里添加A 的v4地址,这里也不起作用了,因为这个v6是如此的优先,以至于不理host table了。当然如果你修改你的程序,是可以从DNS获得v4地址的,然而从另一方面说,这个网络设置是不恰当的,如果你要把B当v4节点,那么就该提供v4优先的DNS解析。这又是一个没有对错的话题,完全取决于你怎么看,而且目前还没有标准答案。
如同前节一样,我还可以给出很多奇怪的例子,大都是应用程序vs网络设置。谁对?谁错?不重要,因为这里还没有best practice。我们QA只负责发现问题,探索问题,而这种近似理念的问题我们只负责上报。 |
|