open***从2.0开始支持server模式,也就是支持多个client连接,之前都是p2p,仅仅是一对连接,一个客户端对应一个服务器,后来有了server模式后,多个客户端可以连接一个服务器,那么随后呢,随后可能就是对等模式了,所有进入***的终端都以完全对等的方式相互可以通信,或者说相互可以建立隧道,这种平等的分布式模型最符合未来的发展,也许鉴于此吧,open***的2.1版本增加了topology选项,有三个可选的模式,分别是net30,p2p和subnet,下面一个一个说,最终引出一个空想的结论。
     net30的名称很怪异,30的意思是什么?其实是一个掩码,ipv4一共32位,30位的掩码余下了两台主机的位置,抛开00和11剩下两台的位置。举一个实例,服务器端启动之后,为tun0配置一个p2p地址:ifconfig tun0 10.0.0.1 pointopoint 10.0.0.2,此时要问10.0.0.2何在?答案是不在,没有这个地址,配置这个地址是为了兼容以前的网络,虽然在ip网下的基于广播的以太网上很难理解这个p2p配置,试想如果不在以太网上,p2p就可以理解了,10.0.0.2是个ip地址,它的下面不一定就是我们熟悉的以太网,如果真的存在一个p2p的链路层,对应10.0.0.2地址的主机是可以有的,并且和10.0.0.1一定是直连,即使该主机不存在,配置这个地址也不多,在服务器启动后会生成两条路由,一条是10.0.0.0/24的网关是10.0.0.2,另一条是10.0.0.2的出口在tun0,有了这两条路由之后,10.0.0.2也就完全成了一个过渡,没有了真实的意义,客户端呢?一样的道理,服务器分配给了客户一个掩码为30个1的ip地址段,然后这个地址段中一个ip地址给了主机,另一个对应的主机不存在(在广播网络中的情况,如在p2p网络中,这个地址对应的主机就存在了,不管那么多了),和服务器是一样的,在广播网络中,这个地址仅仅是个路由过渡的作用。这种设计看起来很丑陋,没有主机的ip地址白白浪费了却一般起不到什么作用,所以open***2.1又提供了另一个模式选项,那就是p2p。
     p2p的名称不诡异,很显然就是点对点,什么意思呢?如果用一种事后诸葛亮的历史观来思考这个问题的话,p2p的模式为subnet埋下了伏笔,起码首先解放了客户端,由于服务器被所有的客户端连接,因此不容易平滑的过渡,所以首先解放分散的客户端,这种历史观也是黄仁宇的历史观,有点大历史的意思,虽然老黄被很多人批驳!p2p模式为客户端不再分配一个掩码为30的地址段,而是分配一个掩码为32的主机地址,这样就为客户端省下了一个ip地址,后事如何,自己思考,很显然,历史观是必须培养的,技术史也一样,历史观有了之后,所有的事情基本都出于同一本原!为了寻求最后的解脱,subnet成了最后的稻草!
     subnet的含义很容易理解,就是将***组建成一个完整并且完全的局域网,服务器的ip可以理解成网关,比如10.0.0.1,仅此一个ip地址,没有别的p2p的地址,客户端的地址也是一样,没有额外的为了兼容的ip地址,也仅仅就一个地址,这样客户端和服务器就成了一个名副其实的局域网了,既然二者构成了一个局域网,再添加新的成员也就很容易了,既然构建***局域网已成趋势,那么服务器和客户端在虚拟链路层的差别也就不再重要了,服务器和客户端仅仅在应用层有意义。接下来就要考虑一旦这个多个客户端和一个服务器组成的***局域网一但形成,它们怎么通信。
     open***提供了client-to-client参数选项,该选项使能了客户端之间的通信,client-to-client的路由,实际上并不是什么三层路由的概念,***服务器在client-to-client网络中并不是一台路由器,而是一台交换机,毕竟局域网通信不需要路由器,虽然这是一个虚拟网卡在广域网上构建的局域网,
     最好的***局域网还不是上面所说的将服务器作为交换机的***局域网,而是一个所有节点完全对等的局域网,所有节点构成分布式网状结构,服务器仅仅实现***局域网的准入验证即可,通信过程完全无需经过***服务器,所有节点之间彼此都可以建立隧道,现在问题是,客户端之间如何实现ssl连接,要有ssl连接,必然需要一个服务器,如此一来,二者又将不再对等,于是我们需要修改我们的准入网模型,一旦该节点是准入的,那么两个准入节点之间的通信将不再认证而仅仅加密,余下的必须完成的认证过程交给各个节点的上层逻辑,于是问题就转化成了如何在通信二者之间协商一个共享密钥,这个就很好办了,kerberos就可以搞定,或者其它?接下来的一个问题是如何使得任何两个节点间可以建立隧道,如果如此,则它们必然要知道彼此的真实公网ip地址,这个其实不难办到,让所有的节点都加上学习功能即可,所有学习的内容由服务器下发(push),每两个client之间的第一次通信必然要经过服务器,然后服务器告知通信双方对端的真实公网地址,于是接下来的通信就不需要服务器了,这就卸载了服务器的很多负载,如果你在局域网上总觉得这个方案太麻烦或者不可理喻,那么放到广域网试试。理论是这样,那么实际上数据如何通信呢?
     一个客户端的tun0的ip为10.0.0.3,真实公网ip为23.12.34.56,另一个客户端的tun0的ip为10.0.0.4,真实公网ip为32.21.43.65,它们同时连接在tun0地址为10.0.0.1,真实地址为100.100.100.1的***服务器上,曾经的一张字迹很丑的手绘图片已经解释了客户端和服务器如何通信,现在看看客户端之间如何通信,以ping为例,第一次0.3的机器ping0.4的机器,通过路由进行隧道封装,数据到达了0.1,然后直达open***,此时进入open***的数据是一个源ip为0.3,目的ip为0.4的原始数据“流”,然后open***将之写入tun0,经过路由后,数据被写入tun0,从而又进入应用层的open***,此时,open***剖析出目的地址是10.0.0.4,属于***网段但是不是自己,那么它查看自己是否设置了client-to-client,如果设置了,那么它会查询自己的连接表,发现32.21.43.65作为客户端连接了自己,它的***地址为10.0.0.4,于是服务器查看32.21.43.65的路由,并且将源ip为0.3,目的为0.4的数据包连同ip头加封一个源为服务器真实ip,目的为0.4真实ip的ip头发给了***地址为0.4的客户端,接下来服务器将0.3和0.4客户端的真实地址分别发给了0.4和0.3,以期望它们能自己建立隧道,...,数据到达0.4之后,经过open***的转发,数据最终进入tun0接收,最终tun0发现就是它要的数据,于是传输终止,数据顺利到达。第二次通信时,0.3和0.4就可以利用从0.1服务器学习而来的ip地址信息自行建立隧道进行通信,当然建立隧道时要付出一些“代价”,那就是协商密钥,kerberos和ssl,自己看着办吧。
     事到如此,一切很合理,从最初的p2p的***,到subnet的***,最终分布式的革命热情不可收拾,一切真的很合理。最后不得不利用ip over ssl的合理与成功来抨击一下IPSec,tun/tap驱动可以实现userspace的IPSec,要想和kernel中的IPSec一致,需要在用户空间得到发往虚拟网卡的IP包以后经IPSec相关的协议封装后用raw-IP发送出去,实现和内核的IPSec同样语义的基础上带来的好处就是解决了穿越nat的问题,实际上可以保持和内核***的一致,但是更灵活。net30完全是一个p2p模型,p2p是个过渡,subnet实现了一个适用于广播型网络比如以太网的***模型,从此,如果***风靡了,那么估计就会有很多人不再必须知道什么是以太网交换机设备了,他们只需要能在***的subnet上驰骋就可以了,正如如今的很多高级开发工程师并不很精通体系结构和汇编,甚至没怎么写过c代码,也不甚懂OS和DBS,但是他们依然很优秀,世界多彩了,灵活了,分工也就更加精细了。