20世纪最激动人心的东西太多了,我最喜欢的相对论算一个,然而在工程界,我觉得最伟大的发明就是TCP/IP,没有之一!它从单台的计算机互联,到承载着如今爆炸式的互联网以及今后的物联网过程中,一直都很优秀,并且最激动人心的是,它几乎还是保持着它刚出生的样子,如此的稳定!不变性本身就是美,就是永恒!再次读到大师的《The design philosophy of the DARPA internet protocols》,感觉有写点东西的必要了。
读史使人明智,确实如此,想了解一个事件或者一种技术的深邃内涵,一定要历史地看!因为所有事物都是稍瞬即逝,要想彻底把握它,必须要了解它的前身和后世,如果你不了解太阳巨石文化和罗马帝国和美索不达米亚,你就很难理解今天西方国家的政策和行为...如果你理解了商周文化和先秦地缘政治学,你就会知道,其实汉字并非人们想象的那样博大精深!对待技术也一样,了解技术历史虽然不能让你写出规范的代码,但它可以让你有可能创造出一个从来没有的东西,而这正是最激动人心的,否则,你掌握的仅仅是一门匠艺,最终会被新的更多的匠艺所淹没。
一.TCP/IP的进化历史概述
-1.最初,TCP/IP是这个样子:
注意,TCP/IP在最初并不是这么拼写的,也没有分层结构,它只是为了解决计算机互联而被设计出来的,今后的发展围绕着原始需求逐渐加入了设计哲学这个手柄,正如Dave Clark说的那样。
IP的分离:这是一桩大事件,IP协议从TCP中分离出来,成了TCP/IP,或者TCP over IP。至于为何分离,设计哲学给出了答案,具体的分析下面详述。IP仅仅是一个报文分组交换的复用层,为了提供IP尽力而为(下文将反复强调,它并没有尽力)的语义,UDP被作为一个端到端的复用层被设计出来,其实UDP就是端系统的IP,而IP则贯穿端系统节点和中间节点。我们从IP报文的分组交换出发,审视TCP/IP这幅美丽的画卷:
0.IP报文交换
IP报文交换是核心中的核心,既然IP从TCP中分离以后就成了一个最大公因子,那么它的职责就是负责传输报文,这也是分组交换的核心思想,由此衍生出来的原则就是IP不能处理任何和服务类别相关的控制功能,比如丢包重传,按序交付等等(流量工程,SDN之类的属于外延的控制,不是IP内在的秉性)。我们可以反过来来理解这个核心中的核心,如果IP实现了丢包重传,按序交付,那么那些不需要该功能的服务的效率会被拖累,也正是因为这样,IP才从TCP中分离开!由此自然而然的得到了上述第一个结论,那就是和服务类型相关的控制功能必须是端到端的行为实现!我们得到一个推论:
1.端到端的传输控制
IP协议自分离以来就是尽力交付的,事实上也真的看不出它“尽力”,它只是逐跳地例行公事罢了!那么对于那些原本的需要丢包重传,按序交付的服务怎么办,这就是留下来的TCP的功能,事实上,现在的TCP把包交换的功能分给IP了,自己仅仅留下了一个控制功能,履行端到端的传输控制。端到端的传输控制思想源头之一是为了减轻中间节点实现传输控制的复杂性,由此可见,阻力有时候也能带来创新,人穷则思变。于是TCP/IP变成了下面的样子:
之所以把IP和TCP分离的另一个原因是需要支持无需重传,无需按序交付的服务,既然现在IP已经纯粹变成了一个包交换传输协议,那么就可以创造一种和和TCP并列的UDP协议同样使用IP的服务,只是刨去TCP的传输控制功能了,印证一句名言:加一个层!于是TCP/IP成了下面的这个样子:
于是,分层模型就出来了,这直接影响了后面几十年!于是一个自然而然的推论就出来了:
2.应用层的高度的可扩展性
分层模型之后,百花齐放的时代到了,既然TCP和UDP都能复用IP,那么TCP之上,UDP之上的多种服用同样也能复用TCP和UDP。看看下面的这个图即可:
仅仅说明一点,应用程序之所以可以爆炸式增长,得益于端到端的传输控制以及分层模型,我们还是反过来考虑这个问题,如果没有端到端的控制,那么每实现或者优化一种传输控制功能,都需要修改中间节点的实现,而想让节点的实现者们为了支持一种协议达成共识是不可能的。如果没有分层模型,中间节点就会显得不像现在这么标准化(封闭),任何的应用创新都可能波及到中间节点,以至于应用创新几乎不可能!(如今的SDN可能或多或少的改变了)
但是,实际的协议栈是一个沙漏而不是一个倒立的锥子!因为我们一直都忽略了实际的物理链路网络!实际上是这个样子:
因此,事情远不像Internet的设计者开始想的那么完美,事实上,在这些链路层以及物理层被设计出来的时候,分层架构还远没有深入人心,并且也借鉴了电话交换网的一些现有思想和技术,所以才造成了很多重复设计,比如X.25的链路级别的重传和TCP的端到端的重传,然而不管怎样,下层的传输控制都是链路级别的,其设计不会影响到整个Internet全局,比如TCP重传会导致一个重传报文穿越整个端到端的所有链路,进而会引发更多的不可控的事件,比如TCP封装TCP时的重传叠加等。
说起TCP封装TCP,TCP/IP的分层架构可以使分层递归化,一个TCP/IP分层实际上带表了一个逻辑网络,真实的网络可以将任意的层作为任意层的payload,进而使VPN的实现成为可能,VPN就是典型的一种物理网络上的逻辑网络!总之,分层模式允许任意层面的封装,TCP/IP于是是下面的样子:
仅仅考虑TCP/IP,我们看到IP是一个逻辑意义上最底层的传输协议,然而数据需要跨越物理链路传输,IP层面以下就是物理链路的最上层了,因此我们有了下面的推论:
3.以往的传输网络退化成了IP的下层
分层模型提出后,各大标准争相靠拢,当时IP并未取得统治地位,可以说ATM,X.25等网络完全实现了分层模型,它们并非一定要使用IP协议,它们本身就是类似IP协议的技术,只是实现更加复杂,对上层和下层提出了很多假设,它们和TCP/IP栈是平行的。最终TCP/IP的IP完胜,鉴于以往的投资以及上述广域网技术的成熟,它们统统退化成了一种链路层技术,这个退化直接得益于分层模式的递归特性,该特性允许逻辑意义的任意封装和再封装!
附:端到端传输控制与路由快速恢复
话说TCP/IP协议栈采用了美丽的端到端控制,IP仅仅保留了分组交换的功能,这个设计出了衍生出了大量的应用之外,还有一个重中之重,那就是使得路由可以快速恢复,怎么说呢?如果和服务应用相关的传输控制特性在IP中实现,那么整个中间节点加上端系统都要支持诸如状态(N元组)的初始化,复制,处理,销毁等操作,以现今的路由协议为例,如果一条链路出现故障,路由协议将不能简单地将IP报文重路由到另外一条路径,此处的复杂性包含但不限于和所有相关端系统的状态的复制操作,即使复制操作得以实现,如果复制的时机和端系统的状态机没有正确对应,会出现意想不到的错误,而这个错误可能是无法恢复的,直接的后果就是端到端通信的中断,这将违背IP协议对应用的透明性原则。(可以参见《再次深入到ip_conntrack的conntrack full问题 》)
不管怎样,确实是端到端的传输控制直接导致路由的简单性,很多路由协议和TCP/IP栈是低度耦合的,比如IS-IS协议。最终,路由的工作就是简单根据IP报头来寻找下一跳,没有任何附加的复杂性,在这个原则之上,开发出了很多的动态路由协议用来支持IP网络故障的自动恢复而不用让端系统感知到这种故障!虽然说策略路由和QoS很大程度上被归为IP协议的范畴,导致了IP的复杂性,然而我认为那只是控制平面的一些有针对性的增强和优化,并没有改变IP简单的秉性!简单就是一切,简单可以应付进化和突变,找个领域的另一个例子是以太网,还有一个终极一点的例子,那就是DNA,再终极一点,就是阴和阳了!
附:简单的IP衍生复杂的控制
IP报文的交换甚至都不是尽力而为,它确实是转发后就不管了,然而它却能保证端到端通信在任意中间节点失效时的快速恢复。如果你说IP的无状态特征使管理和统计很困难的话,那是因为没有考虑控制平面,IP报头的简单性和规整性使得控制平面的实现者可以高效方便的解析协议首部从而将一个数据报文和一个N元组关联起来,进而定义一个流,然后对该流实施任意的控制,目前而言,NAT,状态防火墙,深度解析,入侵检测,VPN等系统都是上述控制平面的实例,将来,SDN将这一切统一起来!
一个协议如此简陋的出身,注定将来大展宏图,所谓英雄不问出处!IP协议和Linux很像,从超级计算机到嵌入式设备,都有它的身影,其背后的原则正是:简单的内秉可以衍生任意的外延!
二.问题以及解决
起初的设计被认为是一个开放式的设计,最终进化成了如今的基于TCP/IP的Internet,可是问题逐渐显现,如果在框架内解决不了,那就说明起初的设计还不够开放和可扩展,事实上最终我们发现IP协议设计得如此精妙,以至于可以设计出任意的控制平面施加于它而得不到它的任何抱怨!
1.问题:端到端的传输控制真的没有问题吗?
过去,网络节点不多,大家满足于分组交换这个简单又实用的网络,所有的复杂性全部由端系统实现,中间节点只负责逐跳将分组交换到目的地端系统,导致了中间节点对应用和服务完全不知情,它无法辨别一个报文是原始报文还是重传报文,当这个越来越严重的时候,便在中间节点引入了越来越多的复杂功能,比如流量工程等,这在某种层面上违背了IP的原始设计理念,然而却是必要的,因为IP协议从一开始就缺乏一个有效且足够复杂的控制层或者说控制平面,IP的设计理念应该是:提供足够简单且灵活的分组转发逻辑。这个理念背后的含义应该是:足够简单且灵活的转发逻辑可以衍生出任意复杂的控制逻辑!我们知道,IP真正的做到了简单和灵活,从一开始就是,不管是IP报头,还是路由器的行为,都足够简单,然而Internet上缺乏控制逻辑,其实控制逻辑早就可以构建出来,SDN迟到的原因并不是说技术上的原因,而是原有的架构工作得还足够好!
2.问题:IP报文交换和端到端的割裂
这个问题其实是问题的延伸,然而是另一个层面的探讨。正如发展经济时提倡买车,经济发达时抑制拥堵一样,Internet也经历了类似的过程!诸如不让人家买车-限制新应用开发,单双号限行-低级的调度策略,不让外牌上高架-资源独占,沪C不让进内环内-粗粒度包分类阻止,这些方式都是一些狗屁方式,最终都会遇到自己给自己制造的瓶颈!最根本的方式除了加快基础设施的建设以外,那就是提供高超的调度策略,提供一种端到端的跟踪体系。SDN真实而不是形式上做到了这一点,它可以让人通过编码而不是“买设备-求支持-写配置”的方式来定义网络行为。
记住,这只是一种控制平面的拓展,没有在任何层面增加IP的复杂度。再次重申,IP的简单,灵活(包括行为定义以及报文头)允许任意复杂的控制平面施加于其上!
3.问题:QoS到底由谁来提供
总览TCP/IP,我们发现它是完全逻辑意义上的,没有对底层的物理设施提出任何的假设,虽然有很多的所谓针对不同物理设施的优化算法,但是这种算法也是可插拔的,比如TCP对于高有损链路的拥塞控制优化。实际上,QoS面对的很多问题都是物理意义上的,比如光纤就是比10BASE-T好,因此,首先底层要提供一个QoS保证的最小集,然后让上层的控制平面来对数据包进行调度分拣(比如根据N元组来识别不同的流量),而不是直接在协议层面植入QoS特性,因此我认为IP报头中保存QoS相关的字段并不适合!正如,你首先要有一条宽阔平整的马路,然后才能在上面划分出各种专用车道和路肩。
4.问题:TCP真的很复杂吗
总有人说TCP很复杂,文档太多且杂,然而其核心却是十分简单的!所谓的那些复杂的东西都是一些可插拔的针对特定场景的优化!最原始的TCP是没有延迟确认和捎带确认的,而引入这些机制是为了优化网络行为和提高吞吐量,可是却影响了延迟,为了干掉糊涂窗口,又引入很多优化,正是这些让协议变得复杂起来,如果读一下理论方面的书,单帧的停等协议就是TCP协议的核心!